From ea6f2b8cde7f770d245cc9d3f6df12c3fe28de0d Mon Sep 17 00:00:00 2001 From: karel Date: Mon, 22 Jul 2024 22:10:02 +0100 Subject: [PATCH] feat(sentinel): refactor --- Cargo.lock | 311 +- Cargo.toml | 3 +- sentinel/Cargo.toml | 30 + sentinel/README.md | 15 + sentinel/queries.graphql | 60 + sentinel/schema.graphql | 6025 +++++++++++++++++ sentinel/src/args.rs | 63 + sentinel/src/main.rs | 78 + sentinel/src/report.rs | 22 + sentinel/src/runner.rs | 27 + sentinel/src/sentinel.rs | 27 + .../src/sentinels/check_ibc_trace_latency.rs | 176 + .../src/sentinels/fetch_latest_transfers.rs | 138 + sentinel/src/sentinels/mod.rs | 2 + 14 files changed, 6922 insertions(+), 55 deletions(-) create mode 100644 sentinel/Cargo.toml create mode 100644 sentinel/README.md create mode 100644 sentinel/queries.graphql create mode 100644 sentinel/schema.graphql create mode 100644 sentinel/src/args.rs create mode 100644 sentinel/src/main.rs create mode 100644 sentinel/src/report.rs create mode 100644 sentinel/src/runner.rs create mode 100644 sentinel/src/sentinel.rs create mode 100644 sentinel/src/sentinels/check_ibc_trace_latency.rs create mode 100644 sentinel/src/sentinels/fetch_latest_transfers.rs create mode 100644 sentinel/src/sentinels/mod.rs diff --git a/Cargo.lock b/Cargo.lock index d8c79095ba..2c3bf5f080 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -404,6 +404,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -564,9 +570,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", @@ -595,7 +601,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ - "futures", + "futures 0.3.30", "pharos", "rustc_version", ] @@ -1087,7 +1093,7 @@ dependencies = [ "ethers", "frame-support-procedural", "frunk", - "futures", + "futures 0.3.30", "hex", "hex-literal", "macros", @@ -1456,7 +1462,7 @@ dependencies = [ "enumorph", "ethers", "frame-support-procedural", - "futures", + "futures 0.3.30", "hex", "hex-literal", "ics23", @@ -1556,19 +1562,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", - "clap_derive 4.5.4", + "clap_derive 4.5.8", ] [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -1591,9 +1597,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1724,6 +1730,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + [[package]] name = "cometbft-rpc" version = "0.1.0" @@ -1790,7 +1809,7 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -2104,7 +2123,7 @@ dependencies = [ "crossbeam-deque", "crossbeam-epoch", "crossbeam-queue", - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -2113,7 +2132,7 @@ version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -2123,7 +2142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -2132,7 +2151,7 @@ version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -2141,7 +2160,18 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", ] [[package]] @@ -2736,7 +2766,7 @@ version = "0.1.0" dependencies = [ "base64 0.21.7", "bip39", - "clap 4.5.4", + "clap 4.5.9", "cosmwasm-std 2.0.3", "ed25519-compact", "hex", @@ -2854,7 +2884,7 @@ dependencies = [ "axum 0.7.5", "chain-utils", "chrono", - "clap 4.5.4", + "clap 4.5.9", "dashmap", "prost 0.12.6", "protos", @@ -3063,7 +3093,7 @@ dependencies = [ name = "ensure-blocks" version = "0.0.0" dependencies = [ - "clap 4.5.4", + "clap 4.5.9", "ethers", "reqwest 0.11.27", "tendermint-rpc", @@ -3124,11 +3154,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", + "typeid", ] [[package]] @@ -3614,7 +3645,7 @@ checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" name = "fetch-scroll-codec-test-vectors" version = "0.0.0" dependencies = [ - "clap 4.5.4", + "clap 4.5.9", "ethers", "scroll-api", "scroll-codec", @@ -3914,6 +3945,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + [[package]] name = "futures" version = "0.3.30" @@ -4058,7 +4095,7 @@ dependencies = [ name = "generate-rust-sol-bindings" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap 4.5.9", "ethers-contract-abigen", ] @@ -4186,6 +4223,65 @@ dependencies = [ "scroll 0.11.0", ] +[[package]] +name = "graphql-introspection-query" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2a4732cf5140bd6c082434494f785a19cfb566ab07d1382c3671f5812fed6d" +dependencies = [ + "serde", +] + +[[package]] +name = "graphql-parser" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" +dependencies = [ + "combine", + "thiserror", +] + +[[package]] +name = "graphql_client" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50cfdc7f34b7f01909d55c2dcb71d4c13cbcbb4a1605d6c8bd760d654c1144b" +dependencies = [ + "graphql_query_derive", + "reqwest 0.11.27", + "serde", + "serde_json", +] + +[[package]] +name = "graphql_client_codegen" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e27ed0c2cf0c0cc52c6bcf3b45c907f433015e580879d14005386251842fb0a" +dependencies = [ + "graphql-introspection-query", + "graphql-parser", + "heck 0.4.1", + "lazy_static", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "graphql_query_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83febfa838f898cfa73dfaa7a8eb69ff3409021ac06ee94cfb3d622f6eeb1a97" +dependencies = [ + "graphql_client_codegen", + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "group" version = "0.13.0" @@ -4484,12 +4580,12 @@ dependencies = [ "backon", "base64 0.21.7", "chain-utils", - "clap 4.5.4", + "clap 4.5.9", "color-eyre", "cometbft-rpc", "contracts", "ethers", - "futures", + "futures 0.3.30", "hex", "itertools 0.13.0", "lazy_static", @@ -4881,6 +4977,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "inventory" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" + [[package]] name = "ipnet" version = "2.9.0" @@ -4979,6 +5081,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbbfed4e59ba9750e15ba154fdfd9329cee16ff3df539c2666b70f58cc32105" +[[package]] +name = "json_value_merge" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0a3aadd8aaadfe2be6fd22bbdb5dbc63494ce22b7c124211f684fd757b3215" +dependencies = [ + "serde_json", +] + [[package]] name = "jsonrpsee" version = "0.22.3" @@ -5624,7 +5735,7 @@ source = "git+https://github.com/near/nearcore#5251bd9d830f2ff7ffceeca149f195039 dependencies = [ "actix", "derive_more", - "futures", + "futures 0.3.30", "near-async-derive", "near-o11y 0.0.0", "near-performance-metrics", @@ -5911,7 +6022,7 @@ source = "git+https://github.com/near/nearcore#5251bd9d830f2ff7ffceeca149f195039 dependencies = [ "actix", "base64 0.21.7", - "clap 4.5.4", + "clap 4.5.9", "near-crypto 0.0.0", "near-primitives-core 0.0.0", "once_cell", @@ -5938,7 +6049,7 @@ checksum = "d20762631bc8253030013bbae9b5f0542691edc1aa6722f1e8141cc9b928ae5b" dependencies = [ "actix", "base64 0.21.7", - "clap 4.5.4", + "clap 4.5.9", "near-crypto 0.20.1", "near-fmt 0.20.1", "near-primitives-core 0.20.1", @@ -6002,7 +6113,7 @@ dependencies = [ "actix", "bitflags 1.3.2", "bytes", - "futures", + "futures 0.3.30", "libc", "once_cell", "tokio", @@ -6826,7 +6937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1a6ca9de4c8b00aa7f1a153bd76cb263287155cec642680d79d98706f3d28a" dependencies = [ "async-trait", - "futures", + "futures 0.3.30", "futures-util", "http 0.2.12", "opentelemetry 0.17.0", @@ -7031,7 +7142,7 @@ dependencies = [ name = "parse-wasm-client-type" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap 4.5.9", "unionlabs", ] @@ -7258,7 +7369,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ - "futures", + "futures 0.3.30", "rustc_version", ] @@ -7797,7 +7908,7 @@ dependencies = [ "enumorph", "frame-support-procedural", "frunk", - "futures", + "futures 0.3.30", "itertools 0.12.1", "macros", "queue-msg-macro", @@ -8011,7 +8122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", - "crossbeam-utils", + "crossbeam-utils 0.8.19", ] [[package]] @@ -8087,9 +8198,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -8144,7 +8255,7 @@ dependencies = [ "ethers", "frame-support-procedural", "frunk", - "futures", + "futures 0.3.30", "hex", "hex-literal", "macros", @@ -8667,7 +8778,7 @@ version = "0.1.0" dependencies = [ "enumorph", "ethers", - "futures", + "futures 0.3.30", "hex", "hex-literal", "macros", @@ -8851,6 +8962,31 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +[[package]] +name = "sentinel" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "clap 4.5.9", + "either", + "erased-serde", + "futures 0.3.30", + "graphql_client", + "json_value_merge", + "regex", + "reqwest 0.11.27", + "serde", + "serde_json", + "tokio", + "tokio-timer", + "tracing", + "tracing-subscriber", + "typetag", + "url", +] + [[package]] name = "serde" version = "1.0.203" @@ -9236,7 +9372,7 @@ checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", "bytes", - "futures", + "futures 0.3.30", "httparse", "log", "rand 0.8.5", @@ -9894,7 +10030,7 @@ dependencies = [ "ed25519", "ed25519-consensus", "flex-error", - "futures", + "futures 0.3.30", "num-traits", "once_cell", "prost 0.12.6", @@ -9976,7 +10112,7 @@ dependencies = [ "async-tungstenite", "bytes", "flex-error", - "futures", + "futures 0.3.30", "getrandom 0.2.12", "peg", "pin-project", @@ -10090,7 +10226,7 @@ version = "0.1.0" dependencies = [ "cargo-util-schemas", "cargo_metadata 0.18.1", - "clap 4.5.4", + "clap 4.5.9", "toml 0.8.12", "tracing", "tracing-subscriber", @@ -10221,6 +10357,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "tokio-executor" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" +dependencies = [ + "crossbeam-utils 0.7.2", + "futures 0.1.31", +] + [[package]] name = "tokio-io-timeout" version = "1.2.0" @@ -10332,6 +10478,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-timer" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" +dependencies = [ + "crossbeam-utils 0.7.2", + "futures 0.1.31", + "slab", + "tokio-executor", +] + [[package]] name = "tokio-tungstenite" version = "0.20.1" @@ -10857,12 +11015,42 @@ dependencies = [ "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "typeid" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typetag" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "661d18414ec032a49ece2d56eee03636e43c4e8d577047ab334c0ba892e29aaf" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac73887f47b9312552aa90ef477927ff014d63d1920ca8037c6c1951eab64bb1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "ucd-trie" version = "0.1.6" @@ -10875,7 +11063,7 @@ version = "0.1.0" dependencies = [ "beacon-api", "chain-utils", - "clap 4.5.4", + "clap 4.5.9", "contracts", "cosmwasm-std 1.5.2", "ethers", @@ -11055,7 +11243,7 @@ dependencies = [ "borsh 1.5.1", "bs58 0.4.0", "chrono", - "clap 4.5.4", + "clap 4.5.9", "contracts", "cosmwasm-std 1.5.2", "derive_more", @@ -11101,7 +11289,7 @@ dependencies = [ name = "unionvisor" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap 4.5.9", "color-eyre", "figment", "fs_extra", @@ -11116,6 +11304,15 @@ dependencies = [ "tracing-test", ] +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -11153,9 +11350,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -11223,6 +11420,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "voyager" version = "0.1.0" @@ -11235,7 +11438,7 @@ dependencies = [ "bitvec", "block-message", "chain-utils", - "clap 4.5.4", + "clap 4.5.9", "contracts", "crossbeam-queue", "derive_more", @@ -11244,7 +11447,7 @@ dependencies = [ "ethers", "frame-support-procedural", "frunk", - "futures", + "futures 0.3.30", "hex", "hex-literal", "itertools 0.13.0", @@ -11287,7 +11490,7 @@ dependencies = [ "arbitrary", "block-message", "chain-utils", - "futures", + "futures 0.3.30", "hex-literal", "macros", "queue-msg", @@ -11704,7 +11907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" dependencies = [ "async_io_stream", - "futures", + "futures 0.3.30", "js-sys", "log", "pharos", @@ -11824,7 +12027,7 @@ dependencies = [ "bzip2", "constant_time_eq 0.1.5", "crc32fast", - "crossbeam-utils", + "crossbeam-utils 0.8.19", "flate2", "hmac 0.12.1", "pbkdf2 0.11.0", diff --git a/Cargo.toml b/Cargo.toml index 225312a8d1..af5ac9d5bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ members = [ "near/near-ibc-tests", "drip", + "sentinel", ] [workspace.package] @@ -153,7 +154,7 @@ bitvec = { version = "1.0.1", default-features = false } borsh = { version = "1.5.0", default-features = false } bytes = { version = "1.2.1", default-features = false } chrono = { version = "0.4.26", default-features = false } -clap = { version = "4.3.0", default-features = false, features = ["std"] } # clap has a fake std feature that is required to be enabled by default +clap = { version = "4.5.9", default-features = false, features = ["std"] } # clap has a fake std feature that is required to be enabled by default color-eyre = { version = "0.6.2", default-features = false } cosmwasm-schema = { version = "1.5", default-features = false } cosmwasm-std = { version = "1.5", default-features = false } diff --git a/sentinel/Cargo.toml b/sentinel/Cargo.toml new file mode 100644 index 0000000000..e85a4abd6d --- /dev/null +++ b/sentinel/Cargo.toml @@ -0,0 +1,30 @@ +[package] +edition.workspace = true +license-file.workspace = true +name = "sentinel" +repository.workspace = true +version = "0.1.0" + +[dependencies] +anyhow = "1.0.86" +async-trait = "0.1.81" +chrono = { workspace = true, features = ["serde", "std", "now"] } +clap = { workspace = true, features = ["derive", "usage", "help", "std"] } +either = { workspace = true, features = ["serde"] } +erased-serde = "0.4.5" +futures = { workspace = true, features = ["std"] } +graphql_client = { version = "0.14.0", features = ["reqwest"] } +json_value_merge = "2.0.0" +regex = "1.10.5" +reqwest.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tokio-timer = "0.2.13" +tracing-subscriber = { workspace = true, features = ["env-filter"] } +tracing.workspace = true +typetag = "0.2.16" +url = { version = "2.5.2", features = ["serde"] } + +[lints] +workspace = true diff --git a/sentinel/README.md b/sentinel/README.md new file mode 100644 index 0000000000..fd7c017593 --- /dev/null +++ b/sentinel/README.md @@ -0,0 +1,15 @@ +# Sentinel + +Sentinels are e2e tests which can continiously run against production environments to ensure that +Union is fully functional. + +## Usage + +Each sentinel has a sane default configuration, as well as that their configuration can be (partially) overridden by +passing a JSON object to the run command + +```bash +cargo run -- run --overrides '{"check_ibc_trace_latency": {"limit": 10}}' # change the limit config of check_ibc_trace_latency, but leave everything else identical. +``` + +Individual tests can be run by passing a regex to filter, which cause only the matches to be run. \ No newline at end of file diff --git a/sentinel/queries.graphql b/sentinel/queries.graphql new file mode 100644 index 0000000000..ceefb45560 --- /dev/null +++ b/sentinel/queries.graphql @@ -0,0 +1,60 @@ + query LastTransfersLimit($limit: Int!) { + v0_transfers(limit: $limit, order_by: {source_timestamp: desc}) { + assets + destination_block_hash + destination_chain_id + destination_channel_id + destination_connection_id + destination_data + destination_height + destination_id + destination_json + destination_port + destination_sequence + destination_timeout_timestamp + destination_timestamp + destination_transaction_hash + destination_transaction_index + is_initiating + normalized_receiver + normalized_sender + packet_data_jsonb + pfm_destination_channel + pfm_destination_port + pfm_recv_sequence + pfm_sent_sequence + pfm_source_channel + pfm_source_port + receiver + sender + source_block_hash + source_chain_id + source_channel_id + source_connection_id + source_data + source_height + source_id + source_json + source_port + source_sequence + source_timeout_timestamp + source_timestamp + source_transaction_hash + source_transaction_index + status + transaction_hash + } +} + +query LastTransfersWithTraces($limit: Int!, $source_time: timestamptz!) { + v0_transfers(limit: $limit, order_by: {source_timestamp: desc}, where: {source_timestamp: {_lte: $source_time}}) { + source_timestamp + traces(order_by: {timestamp: asc}) { + chain_id + initiating_transaction_hash + timestamp + transaction_hash + type + } + } +} \ No newline at end of file diff --git a/sentinel/schema.graphql b/sentinel/schema.graphql new file mode 100644 index 0000000000..fb47594437 --- /dev/null +++ b/sentinel/schema.graphql @@ -0,0 +1,6025 @@ +schema { + query: query_root + mutation: mutation_root + subscription: subscription_root +} + +"""whether this query should be cached (Hasura Cloud only)""" +directive @cached( + """measured in seconds""" + ttl: Int! = 60 + + """refresh the cache entry""" + refresh: Boolean! = false +) on QUERY + +""" +Boolean expression to compare columns of type "Boolean". All fields are combined with logical 'AND'. +""" +input Boolean_comparison_exp { + _eq: Boolean + _gt: Boolean + _gte: Boolean + _in: [Boolean!] + _is_null: Boolean + _lt: Boolean + _lte: Boolean + _neq: Boolean + _nin: [Boolean!] +} + +""" +Boolean expression to compare columns of type "Int". All fields are combined with logical 'AND'. +""" +input Int_comparison_exp { + _eq: Int + _gt: Int + _gte: Int + _in: [Int!] + _is_null: Boolean + _lt: Int + _lte: Int + _neq: Int + _nin: [Int!] +} + +type Mutation { + send(captchaToken: String!, toAddress: String!): String! +} + +""" +Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. +""" +input String_comparison_exp { + _eq: String + _gt: String + _gte: String + + """does the column match the given case-insensitive pattern""" + _ilike: String + _in: [String!] + + """ + does the column match the given POSIX regular expression, case insensitive + """ + _iregex: String + _is_null: Boolean + + """does the column match the given pattern""" + _like: String + _lt: String + _lte: String + _neq: String + + """does the column NOT match the given case-insensitive pattern""" + _nilike: String + _nin: [String!] + + """ + does the column NOT match the given POSIX regular expression, case insensitive + """ + _niregex: String + + """does the column NOT match the given pattern""" + _nlike: String + + """ + does the column NOT match the given POSIX regular expression, case sensitive + """ + _nregex: String + + """does the column NOT match the given SQL regular expression""" + _nsimilar: String + + """ + does the column match the given POSIX regular expression, case sensitive + """ + _regex: String + + """does the column match the given SQL regular expression""" + _similar: String +} + +scalar bigint + +""" +Boolean expression to compare columns of type "bigint". All fields are combined with logical 'AND'. +""" +input bigint_comparison_exp { + _eq: bigint + _gt: bigint + _gte: bigint + _in: [bigint!] + _is_null: Boolean + _lt: bigint + _lte: bigint + _neq: bigint + _nin: [bigint!] +} + +"""ordering argument of a cursor""" +enum cursor_ordering { + """ascending ordering of the cursor""" + ASC + + """descending ordering of the cursor""" + DESC +} + +type faucet2Query { + howdy: String! +} + +scalar json + +scalar jsonb + +input jsonb_cast_exp { + String: String_comparison_exp +} + +""" +Boolean expression to compare columns of type "jsonb". All fields are combined with logical 'AND'. +""" +input jsonb_comparison_exp { + _cast: jsonb_cast_exp + + """is the column contained in the given json value""" + _contained_in: jsonb + + """does the column contain the given json value at the top level""" + _contains: jsonb + _eq: jsonb + _gt: jsonb + _gte: jsonb + + """does the string exist as a top-level key in the column""" + _has_key: String + + """do all of these strings exist as top-level keys in the column""" + _has_keys_all: [String!] + + """do any of these strings exist as top-level keys in the column""" + _has_keys_any: [String!] + _in: [jsonb!] + _is_null: Boolean + _lt: jsonb + _lte: jsonb + _neq: jsonb + _nin: [jsonb!] +} + +"""mutation root""" +type mutation_root { + faucet2: Mutation +} + +scalar numeric + +""" +Boolean expression to compare columns of type "numeric". All fields are combined with logical 'AND'. +""" +input numeric_comparison_exp { + _eq: numeric + _gt: numeric + _gte: numeric + _in: [numeric!] + _is_null: Boolean + _lt: numeric + _lte: numeric + _neq: numeric + _nin: [numeric!] +} + +"""column ordering options""" +enum order_by { + """in ascending order, nulls last""" + asc + + """in ascending order, nulls first""" + asc_nulls_first + + """in ascending order, nulls last""" + asc_nulls_last + + """in descending order, nulls first""" + desc + + """in descending order, nulls first""" + desc_nulls_first + + """in descending order, nulls last""" + desc_nulls_last +} + +type query_root { + faucet2: faucet2Query + + """ + fetch data from the table: "v0.assets" + """ + v0_assets( + """distinct select on columns""" + distinct_on: [v0_assets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_assets_order_by!] + + """filter the rows returned""" + where: v0_assets_bool_exp + ): [v0_assets!]! + + """fetch data from the table: "v0.assets" using primary key columns""" + v0_assets_by_pk(chain_id: Int!, denom: String!): v0_assets + + """ + fetch data from the table: "v0.blocks" + """ + v0_blocks( + """distinct select on columns""" + distinct_on: [v0_blocks_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_blocks_order_by!] + + """filter the rows returned""" + where: v0_blocks_bool_exp + ): [v0_blocks!]! + + """fetch data from the table: "v0.blocks" using primary key columns""" + v0_blocks_by_pk(chain_id: Int!, hash: String!): v0_blocks + + """ + fetch data from the table: "v0.chains" + """ + v0_chains( + """distinct select on columns""" + distinct_on: [v0_chains_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_chains_order_by!] + + """filter the rows returned""" + where: v0_chains_bool_exp + ): [v0_chains!]! + + """fetch data from the table: "v0.chains" using primary key columns""" + v0_chains_by_pk(id: Int!): v0_chains + + """ + fetch data from the table: "v0.channel_map" + """ + v0_channel_map( + """distinct select on columns""" + distinct_on: [v0_channel_map_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channel_map_order_by!] + + """filter the rows returned""" + where: v0_channel_map_bool_exp + ): [v0_channel_map!]! + + """ + fetch data from the table: "v0.channels" + """ + v0_channels( + """distinct select on columns""" + distinct_on: [v0_channels_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channels_order_by!] + + """filter the rows returned""" + where: v0_channels_bool_exp + ): [v0_channels!]! + + """ + fetch aggregated fields from the table: "v0.channels" + """ + v0_channels_aggregate( + """distinct select on columns""" + distinct_on: [v0_channels_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channels_order_by!] + + """filter the rows returned""" + where: v0_channels_bool_exp + ): v0_channels_aggregate! + + """ + fetch data from the table: "v0.connection_map" + """ + v0_connection_map( + """distinct select on columns""" + distinct_on: [v0_connection_map_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_connection_map_order_by!] + + """filter the rows returned""" + where: v0_connection_map_bool_exp + ): [v0_connection_map!]! + + """ + fetch data from the table: "v0.connections" + """ + v0_connections( + """distinct select on columns""" + distinct_on: [v0_connections_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_connections_order_by!] + + """filter the rows returned""" + where: v0_connections_bool_exp + ): [v0_connections!]! + + """ + fetch data from the table: "v0.daily_packets" + """ + v0_daily_packets( + """distinct select on columns""" + distinct_on: [v0_daily_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_daily_packets_order_by!] + + """filter the rows returned""" + where: v0_daily_packets_bool_exp + ): [v0_daily_packets!]! + + """ + fetch data from the table: "v0.daily_transfers" + """ + v0_daily_transfers( + """distinct select on columns""" + distinct_on: [v0_daily_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_daily_transfers_order_by!] + + """filter the rows returned""" + where: v0_daily_transfers_bool_exp + ): [v0_daily_transfers!]! + + """ + fetch data from the table: "v0.explorers" + """ + v0_explorers( + """distinct select on columns""" + distinct_on: [v0_explorers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_explorers_order_by!] + + """filter the rows returned""" + where: v0_explorers_bool_exp + ): [v0_explorers!]! + + """fetch data from the table: "v0.explorers" using primary key columns""" + v0_explorers_by_pk(id: Int!): v0_explorers + + """ + fetch data from the table: "v0.faucets" + """ + v0_faucets( + """distinct select on columns""" + distinct_on: [v0_faucets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_faucets_order_by!] + + """filter the rows returned""" + where: v0_faucets_bool_exp + ): [v0_faucets!]! + + """fetch data from the table: "v0.faucets" using primary key columns""" + v0_faucets_by_pk(chain_id: Int!, url: String!): v0_faucets + + """ + execute function "v0.get_transfer_forwards" which returns "v0.transfer_forwards" + """ + v0_get_transfer_forwards( + """ + input parameters for function "v0_get_transfer_forwards" + """ + args: v0_get_transfer_forwards_args! + + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + fetch data from the table: "v0.index_status" + """ + v0_index_status( + """distinct select on columns""" + distinct_on: [v0_index_status_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_index_status_order_by!] + + """filter the rows returned""" + where: v0_index_status_bool_exp + ): [v0_index_status!]! + + """ + fetch data from the table: "v0.packets" + """ + v0_packets( + """distinct select on columns""" + distinct_on: [v0_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_order_by!] + + """filter the rows returned""" + where: v0_packets_bool_exp + ): [v0_packets!]! + + """ + fetch aggregated fields from the table: "v0.packets" + """ + v0_packets_aggregate( + """distinct select on columns""" + distinct_on: [v0_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_order_by!] + + """filter the rows returned""" + where: v0_packets_bool_exp + ): v0_packets_aggregate! + + """ + fetch data from the table: "v0.packets_mat" + """ + v0_packets_mat( + """distinct select on columns""" + distinct_on: [v0_packets_mat_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_mat_order_by!] + + """filter the rows returned""" + where: v0_packets_mat_bool_exp + ): [v0_packets_mat!]! + + """ + fetch aggregated fields from the table: "v0.packets_mat" + """ + v0_packets_mat_aggregate( + """distinct select on columns""" + distinct_on: [v0_packets_mat_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_mat_order_by!] + + """filter the rows returned""" + where: v0_packets_mat_bool_exp + ): v0_packets_mat_aggregate! + + """ + fetch data from the table: "v0.rpcs" + """ + v0_rpcs( + """distinct select on columns""" + distinct_on: [v0_rpcs_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_rpcs_order_by!] + + """filter the rows returned""" + where: v0_rpcs_bool_exp + ): [v0_rpcs!]! + + """fetch data from the table: "v0.rpcs" using primary key columns""" + v0_rpcs_by_pk(chain_id: Int!, url: String!): v0_rpcs + + """ + fetch data from the table: "v0.traces" + """ + v0_traces( + """distinct select on columns""" + distinct_on: [v0_traces_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_traces_order_by!] + + """filter the rows returned""" + where: v0_traces_bool_exp + ): [v0_traces!]! + + """ + fetch data from the table: "v0.transactions" + """ + v0_transactions( + """distinct select on columns""" + distinct_on: [v0_transactions_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transactions_order_by!] + + """filter the rows returned""" + where: v0_transactions_bool_exp + ): [v0_transactions!]! + + """fetch data from the table: "v0.transactions" using primary key columns""" + v0_transactions_by_pk(chain_id: Int!, hash: String!): v0_transactions + + """ + fetch data from the table: "v0.transfer_forwards" + """ + v0_transfer_forwards( + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + fetch data from the table: "v0.transfers" + """ + v0_transfers( + """distinct select on columns""" + distinct_on: [v0_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfers_order_by!] + + """filter the rows returned""" + where: v0_transfers_bool_exp + ): [v0_transfers!]! + + """ + fetch aggregated fields from the table: "v0.transfers" + """ + v0_transfers_aggregate( + """distinct select on columns""" + distinct_on: [v0_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfers_order_by!] + + """filter the rows returned""" + where: v0_transfers_bool_exp + ): v0_transfers_aggregate! + + """ + fetch data from the table: "v0.ucs1_configuration" + """ + v0_ucs1_configuration( + """distinct select on columns""" + distinct_on: [v0_ucs1_configuration_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_ucs1_configuration_order_by!] + + """filter the rows returned""" + where: v0_ucs1_configuration_bool_exp + ): [v0_ucs1_configuration!]! + + """ + fetch data from the table: "v0.ucs1_configuration" using primary key columns + """ + v0_ucs1_configuration_by_pk(destination_chain_id: Int!, source_chain_id: Int!): v0_ucs1_configuration +} + +input status_v0_transactions_args { + hasura_session: json +} + +type subscription_root { + """ + fetch data from the table: "v0.assets" + """ + v0_assets( + """distinct select on columns""" + distinct_on: [v0_assets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_assets_order_by!] + + """filter the rows returned""" + where: v0_assets_bool_exp + ): [v0_assets!]! + + """fetch data from the table: "v0.assets" using primary key columns""" + v0_assets_by_pk(chain_id: Int!, denom: String!): v0_assets + + """ + fetch data from the table in a streaming manner: "v0.assets" + """ + v0_assets_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_assets_stream_cursor_input]! + + """filter the rows returned""" + where: v0_assets_bool_exp + ): [v0_assets!]! + + """ + fetch data from the table: "v0.blocks" + """ + v0_blocks( + """distinct select on columns""" + distinct_on: [v0_blocks_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_blocks_order_by!] + + """filter the rows returned""" + where: v0_blocks_bool_exp + ): [v0_blocks!]! + + """fetch data from the table: "v0.blocks" using primary key columns""" + v0_blocks_by_pk(chain_id: Int!, hash: String!): v0_blocks + + """ + fetch data from the table in a streaming manner: "v0.blocks" + """ + v0_blocks_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_blocks_stream_cursor_input]! + + """filter the rows returned""" + where: v0_blocks_bool_exp + ): [v0_blocks!]! + + """ + fetch data from the table: "v0.chains" + """ + v0_chains( + """distinct select on columns""" + distinct_on: [v0_chains_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_chains_order_by!] + + """filter the rows returned""" + where: v0_chains_bool_exp + ): [v0_chains!]! + + """fetch data from the table: "v0.chains" using primary key columns""" + v0_chains_by_pk(id: Int!): v0_chains + + """ + fetch data from the table in a streaming manner: "v0.chains" + """ + v0_chains_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_chains_stream_cursor_input]! + + """filter the rows returned""" + where: v0_chains_bool_exp + ): [v0_chains!]! + + """ + fetch data from the table: "v0.channel_map" + """ + v0_channel_map( + """distinct select on columns""" + distinct_on: [v0_channel_map_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channel_map_order_by!] + + """filter the rows returned""" + where: v0_channel_map_bool_exp + ): [v0_channel_map!]! + + """ + fetch data from the table in a streaming manner: "v0.channel_map" + """ + v0_channel_map_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_channel_map_stream_cursor_input]! + + """filter the rows returned""" + where: v0_channel_map_bool_exp + ): [v0_channel_map!]! + + """ + fetch data from the table: "v0.channels" + """ + v0_channels( + """distinct select on columns""" + distinct_on: [v0_channels_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channels_order_by!] + + """filter the rows returned""" + where: v0_channels_bool_exp + ): [v0_channels!]! + + """ + fetch aggregated fields from the table: "v0.channels" + """ + v0_channels_aggregate( + """distinct select on columns""" + distinct_on: [v0_channels_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_channels_order_by!] + + """filter the rows returned""" + where: v0_channels_bool_exp + ): v0_channels_aggregate! + + """ + fetch data from the table in a streaming manner: "v0.channels" + """ + v0_channels_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_channels_stream_cursor_input]! + + """filter the rows returned""" + where: v0_channels_bool_exp + ): [v0_channels!]! + + """ + fetch data from the table: "v0.connection_map" + """ + v0_connection_map( + """distinct select on columns""" + distinct_on: [v0_connection_map_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_connection_map_order_by!] + + """filter the rows returned""" + where: v0_connection_map_bool_exp + ): [v0_connection_map!]! + + """ + fetch data from the table in a streaming manner: "v0.connection_map" + """ + v0_connection_map_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_connection_map_stream_cursor_input]! + + """filter the rows returned""" + where: v0_connection_map_bool_exp + ): [v0_connection_map!]! + + """ + fetch data from the table: "v0.connections" + """ + v0_connections( + """distinct select on columns""" + distinct_on: [v0_connections_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_connections_order_by!] + + """filter the rows returned""" + where: v0_connections_bool_exp + ): [v0_connections!]! + + """ + fetch data from the table in a streaming manner: "v0.connections" + """ + v0_connections_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_connections_stream_cursor_input]! + + """filter the rows returned""" + where: v0_connections_bool_exp + ): [v0_connections!]! + + """ + fetch data from the table: "v0.daily_packets" + """ + v0_daily_packets( + """distinct select on columns""" + distinct_on: [v0_daily_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_daily_packets_order_by!] + + """filter the rows returned""" + where: v0_daily_packets_bool_exp + ): [v0_daily_packets!]! + + """ + fetch data from the table in a streaming manner: "v0.daily_packets" + """ + v0_daily_packets_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_daily_packets_stream_cursor_input]! + + """filter the rows returned""" + where: v0_daily_packets_bool_exp + ): [v0_daily_packets!]! + + """ + fetch data from the table: "v0.daily_transfers" + """ + v0_daily_transfers( + """distinct select on columns""" + distinct_on: [v0_daily_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_daily_transfers_order_by!] + + """filter the rows returned""" + where: v0_daily_transfers_bool_exp + ): [v0_daily_transfers!]! + + """ + fetch data from the table in a streaming manner: "v0.daily_transfers" + """ + v0_daily_transfers_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_daily_transfers_stream_cursor_input]! + + """filter the rows returned""" + where: v0_daily_transfers_bool_exp + ): [v0_daily_transfers!]! + + """ + fetch data from the table: "v0.explorers" + """ + v0_explorers( + """distinct select on columns""" + distinct_on: [v0_explorers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_explorers_order_by!] + + """filter the rows returned""" + where: v0_explorers_bool_exp + ): [v0_explorers!]! + + """fetch data from the table: "v0.explorers" using primary key columns""" + v0_explorers_by_pk(id: Int!): v0_explorers + + """ + fetch data from the table in a streaming manner: "v0.explorers" + """ + v0_explorers_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_explorers_stream_cursor_input]! + + """filter the rows returned""" + where: v0_explorers_bool_exp + ): [v0_explorers!]! + + """ + fetch data from the table: "v0.faucets" + """ + v0_faucets( + """distinct select on columns""" + distinct_on: [v0_faucets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_faucets_order_by!] + + """filter the rows returned""" + where: v0_faucets_bool_exp + ): [v0_faucets!]! + + """fetch data from the table: "v0.faucets" using primary key columns""" + v0_faucets_by_pk(chain_id: Int!, url: String!): v0_faucets + + """ + fetch data from the table in a streaming manner: "v0.faucets" + """ + v0_faucets_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_faucets_stream_cursor_input]! + + """filter the rows returned""" + where: v0_faucets_bool_exp + ): [v0_faucets!]! + + """ + execute function "v0.get_transfer_forwards" which returns "v0.transfer_forwards" + """ + v0_get_transfer_forwards( + """ + input parameters for function "v0_get_transfer_forwards" + """ + args: v0_get_transfer_forwards_args! + + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + fetch data from the table: "v0.index_status" + """ + v0_index_status( + """distinct select on columns""" + distinct_on: [v0_index_status_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_index_status_order_by!] + + """filter the rows returned""" + where: v0_index_status_bool_exp + ): [v0_index_status!]! + + """ + fetch data from the table in a streaming manner: "v0.index_status" + """ + v0_index_status_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_index_status_stream_cursor_input]! + + """filter the rows returned""" + where: v0_index_status_bool_exp + ): [v0_index_status!]! + + """ + fetch data from the table: "v0.packets" + """ + v0_packets( + """distinct select on columns""" + distinct_on: [v0_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_order_by!] + + """filter the rows returned""" + where: v0_packets_bool_exp + ): [v0_packets!]! + + """ + fetch aggregated fields from the table: "v0.packets" + """ + v0_packets_aggregate( + """distinct select on columns""" + distinct_on: [v0_packets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_order_by!] + + """filter the rows returned""" + where: v0_packets_bool_exp + ): v0_packets_aggregate! + + """ + fetch data from the table: "v0.packets_mat" + """ + v0_packets_mat( + """distinct select on columns""" + distinct_on: [v0_packets_mat_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_mat_order_by!] + + """filter the rows returned""" + where: v0_packets_mat_bool_exp + ): [v0_packets_mat!]! + + """ + fetch aggregated fields from the table: "v0.packets_mat" + """ + v0_packets_mat_aggregate( + """distinct select on columns""" + distinct_on: [v0_packets_mat_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_packets_mat_order_by!] + + """filter the rows returned""" + where: v0_packets_mat_bool_exp + ): v0_packets_mat_aggregate! + + """ + fetch data from the table in a streaming manner: "v0.packets_mat" + """ + v0_packets_mat_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_packets_mat_stream_cursor_input]! + + """filter the rows returned""" + where: v0_packets_mat_bool_exp + ): [v0_packets_mat!]! + + """ + fetch data from the table in a streaming manner: "v0.packets" + """ + v0_packets_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_packets_stream_cursor_input]! + + """filter the rows returned""" + where: v0_packets_bool_exp + ): [v0_packets!]! + + """ + fetch data from the table: "v0.rpcs" + """ + v0_rpcs( + """distinct select on columns""" + distinct_on: [v0_rpcs_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_rpcs_order_by!] + + """filter the rows returned""" + where: v0_rpcs_bool_exp + ): [v0_rpcs!]! + + """fetch data from the table: "v0.rpcs" using primary key columns""" + v0_rpcs_by_pk(chain_id: Int!, url: String!): v0_rpcs + + """ + fetch data from the table in a streaming manner: "v0.rpcs" + """ + v0_rpcs_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_rpcs_stream_cursor_input]! + + """filter the rows returned""" + where: v0_rpcs_bool_exp + ): [v0_rpcs!]! + + """ + fetch data from the table: "v0.traces" + """ + v0_traces( + """distinct select on columns""" + distinct_on: [v0_traces_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_traces_order_by!] + + """filter the rows returned""" + where: v0_traces_bool_exp + ): [v0_traces!]! + + """ + fetch data from the table in a streaming manner: "v0.traces" + """ + v0_traces_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_traces_stream_cursor_input]! + + """filter the rows returned""" + where: v0_traces_bool_exp + ): [v0_traces!]! + + """ + fetch data from the table: "v0.transactions" + """ + v0_transactions( + """distinct select on columns""" + distinct_on: [v0_transactions_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transactions_order_by!] + + """filter the rows returned""" + where: v0_transactions_bool_exp + ): [v0_transactions!]! + + """fetch data from the table: "v0.transactions" using primary key columns""" + v0_transactions_by_pk(chain_id: Int!, hash: String!): v0_transactions + + """ + fetch data from the table in a streaming manner: "v0.transactions" + """ + v0_transactions_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_transactions_stream_cursor_input]! + + """filter the rows returned""" + where: v0_transactions_bool_exp + ): [v0_transactions!]! + + """ + fetch data from the table: "v0.transfer_forwards" + """ + v0_transfer_forwards( + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + fetch data from the table in a streaming manner: "v0.transfer_forwards" + """ + v0_transfer_forwards_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_transfer_forwards_stream_cursor_input]! + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + fetch data from the table: "v0.transfers" + """ + v0_transfers( + """distinct select on columns""" + distinct_on: [v0_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfers_order_by!] + + """filter the rows returned""" + where: v0_transfers_bool_exp + ): [v0_transfers!]! + + """ + fetch aggregated fields from the table: "v0.transfers" + """ + v0_transfers_aggregate( + """distinct select on columns""" + distinct_on: [v0_transfers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfers_order_by!] + + """filter the rows returned""" + where: v0_transfers_bool_exp + ): v0_transfers_aggregate! + + """ + fetch data from the table in a streaming manner: "v0.transfers" + """ + v0_transfers_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_transfers_stream_cursor_input]! + + """filter the rows returned""" + where: v0_transfers_bool_exp + ): [v0_transfers!]! + + """ + fetch data from the table: "v0.ucs1_configuration" + """ + v0_ucs1_configuration( + """distinct select on columns""" + distinct_on: [v0_ucs1_configuration_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_ucs1_configuration_order_by!] + + """filter the rows returned""" + where: v0_ucs1_configuration_bool_exp + ): [v0_ucs1_configuration!]! + + """ + fetch data from the table: "v0.ucs1_configuration" using primary key columns + """ + v0_ucs1_configuration_by_pk(destination_chain_id: Int!, source_chain_id: Int!): v0_ucs1_configuration + + """ + fetch data from the table in a streaming manner: "v0.ucs1_configuration" + """ + v0_ucs1_configuration_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [v0_ucs1_configuration_stream_cursor_input]! + + """filter the rows returned""" + where: v0_ucs1_configuration_bool_exp + ): [v0_ucs1_configuration!]! +} + +scalar timestamptz + +""" +Boolean expression to compare columns of type "timestamptz". All fields are combined with logical 'AND'. +""" +input timestamptz_comparison_exp { + _eq: timestamptz + _gt: timestamptz + _gte: timestamptz + _in: [timestamptz!] + _is_null: Boolean + _lt: timestamptz + _lte: timestamptz + _neq: timestamptz + _nin: [timestamptz!] +} + +scalar transfers_scalar + +""" +columns and relationships of "v0.assets" +""" +type v0_assets { + """An object relationship""" + chain: v0_chains! + chain_id: Int! + decimals: Int + denom: String! + display_name: String + display_symbol: String + + """An array relationship""" + faucets( + """distinct select on columns""" + distinct_on: [v0_faucets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_faucets_order_by!] + + """filter the rows returned""" + where: v0_faucets_bool_exp + ): [v0_faucets!]! + gas_token: Boolean! + logo_uri: String +} + +""" +order by aggregate values of table "v0.assets" +""" +input v0_assets_aggregate_order_by { + avg: v0_assets_avg_order_by + count: order_by + max: v0_assets_max_order_by + min: v0_assets_min_order_by + stddev: v0_assets_stddev_order_by + stddev_pop: v0_assets_stddev_pop_order_by + stddev_samp: v0_assets_stddev_samp_order_by + sum: v0_assets_sum_order_by + var_pop: v0_assets_var_pop_order_by + var_samp: v0_assets_var_samp_order_by + variance: v0_assets_variance_order_by +} + +""" +order by avg() on columns of table "v0.assets" +""" +input v0_assets_avg_order_by { + chain_id: order_by + decimals: order_by +} + +""" +Boolean expression to filter rows from the table "v0.assets". All fields are combined with a logical 'AND'. +""" +input v0_assets_bool_exp { + _and: [v0_assets_bool_exp!] + _not: v0_assets_bool_exp + _or: [v0_assets_bool_exp!] + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + decimals: Int_comparison_exp + denom: String_comparison_exp + display_name: String_comparison_exp + display_symbol: String_comparison_exp + faucets: v0_faucets_bool_exp + gas_token: Boolean_comparison_exp + logo_uri: String_comparison_exp +} + +""" +order by max() on columns of table "v0.assets" +""" +input v0_assets_max_order_by { + chain_id: order_by + decimals: order_by + denom: order_by + display_name: order_by + display_symbol: order_by + logo_uri: order_by +} + +""" +order by min() on columns of table "v0.assets" +""" +input v0_assets_min_order_by { + chain_id: order_by + decimals: order_by + denom: order_by + display_name: order_by + display_symbol: order_by + logo_uri: order_by +} + +"""Ordering options when selecting data from "v0.assets".""" +input v0_assets_order_by { + chain: v0_chains_order_by + chain_id: order_by + decimals: order_by + denom: order_by + display_name: order_by + display_symbol: order_by + faucets_aggregate: v0_faucets_aggregate_order_by + gas_token: order_by + logo_uri: order_by +} + +""" +select columns of table "v0.assets" +""" +enum v0_assets_select_column { + """column name""" + chain_id + + """column name""" + decimals + + """column name""" + denom + + """column name""" + display_name + + """column name""" + display_symbol + + """column name""" + gas_token + + """column name""" + logo_uri +} + +""" +order by stddev() on columns of table "v0.assets" +""" +input v0_assets_stddev_order_by { + chain_id: order_by + decimals: order_by +} + +""" +order by stddev_pop() on columns of table "v0.assets" +""" +input v0_assets_stddev_pop_order_by { + chain_id: order_by + decimals: order_by +} + +""" +order by stddev_samp() on columns of table "v0.assets" +""" +input v0_assets_stddev_samp_order_by { + chain_id: order_by + decimals: order_by +} + +""" +Streaming cursor of the table "v0_assets" +""" +input v0_assets_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_assets_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_assets_stream_cursor_value_input { + chain_id: Int + decimals: Int + denom: String + display_name: String + display_symbol: String + gas_token: Boolean + logo_uri: String +} + +""" +order by sum() on columns of table "v0.assets" +""" +input v0_assets_sum_order_by { + chain_id: order_by + decimals: order_by +} + +""" +order by var_pop() on columns of table "v0.assets" +""" +input v0_assets_var_pop_order_by { + chain_id: order_by + decimals: order_by +} + +""" +order by var_samp() on columns of table "v0.assets" +""" +input v0_assets_var_samp_order_by { + chain_id: order_by + decimals: order_by +} + +""" +order by variance() on columns of table "v0.assets" +""" +input v0_assets_variance_order_by { + chain_id: order_by + decimals: order_by +} + +""" +columns and relationships of "v0.blocks" +""" +type v0_blocks { + """An object relationship""" + chain: v0_chains! + chain_id: Int! + data( + """JSON select path""" + path: String + ): jsonb! + hash: String! + height: Int! + time: timestamptz! + + """An array relationship""" + transactions( + """distinct select on columns""" + distinct_on: [v0_transactions_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transactions_order_by!] + + """filter the rows returned""" + where: v0_transactions_bool_exp + ): [v0_transactions!]! +} + +""" +order by aggregate values of table "v0.blocks" +""" +input v0_blocks_aggregate_order_by { + avg: v0_blocks_avg_order_by + count: order_by + max: v0_blocks_max_order_by + min: v0_blocks_min_order_by + stddev: v0_blocks_stddev_order_by + stddev_pop: v0_blocks_stddev_pop_order_by + stddev_samp: v0_blocks_stddev_samp_order_by + sum: v0_blocks_sum_order_by + var_pop: v0_blocks_var_pop_order_by + var_samp: v0_blocks_var_samp_order_by + variance: v0_blocks_variance_order_by +} + +""" +order by avg() on columns of table "v0.blocks" +""" +input v0_blocks_avg_order_by { + chain_id: order_by + height: order_by +} + +""" +Boolean expression to filter rows from the table "v0.blocks". All fields are combined with a logical 'AND'. +""" +input v0_blocks_bool_exp { + _and: [v0_blocks_bool_exp!] + _not: v0_blocks_bool_exp + _or: [v0_blocks_bool_exp!] + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + data: jsonb_comparison_exp + hash: String_comparison_exp + height: Int_comparison_exp + time: timestamptz_comparison_exp + transactions: v0_transactions_bool_exp +} + +""" +order by max() on columns of table "v0.blocks" +""" +input v0_blocks_max_order_by { + chain_id: order_by + hash: order_by + height: order_by + time: order_by +} + +""" +order by min() on columns of table "v0.blocks" +""" +input v0_blocks_min_order_by { + chain_id: order_by + hash: order_by + height: order_by + time: order_by +} + +"""Ordering options when selecting data from "v0.blocks".""" +input v0_blocks_order_by { + chain: v0_chains_order_by + chain_id: order_by + data: order_by + hash: order_by + height: order_by + time: order_by + transactions_aggregate: v0_transactions_aggregate_order_by +} + +""" +select columns of table "v0.blocks" +""" +enum v0_blocks_select_column { + """column name""" + chain_id + + """column name""" + data + + """column name""" + hash + + """column name""" + height + + """column name""" + time +} + +""" +order by stddev() on columns of table "v0.blocks" +""" +input v0_blocks_stddev_order_by { + chain_id: order_by + height: order_by +} + +""" +order by stddev_pop() on columns of table "v0.blocks" +""" +input v0_blocks_stddev_pop_order_by { + chain_id: order_by + height: order_by +} + +""" +order by stddev_samp() on columns of table "v0.blocks" +""" +input v0_blocks_stddev_samp_order_by { + chain_id: order_by + height: order_by +} + +""" +Streaming cursor of the table "v0_blocks" +""" +input v0_blocks_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_blocks_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_blocks_stream_cursor_value_input { + chain_id: Int + data: jsonb + hash: String + height: Int + time: timestamptz +} + +""" +order by sum() on columns of table "v0.blocks" +""" +input v0_blocks_sum_order_by { + chain_id: order_by + height: order_by +} + +""" +order by var_pop() on columns of table "v0.blocks" +""" +input v0_blocks_var_pop_order_by { + chain_id: order_by + height: order_by +} + +""" +order by var_samp() on columns of table "v0.blocks" +""" +input v0_blocks_var_samp_order_by { + chain_id: order_by + height: order_by +} + +""" +order by variance() on columns of table "v0.blocks" +""" +input v0_blocks_variance_order_by { + chain_id: order_by + height: order_by +} + +""" +columns and relationships of "v0.chains" +""" +type v0_chains { + addr_prefix: String + + """An array relationship""" + assets( + """distinct select on columns""" + distinct_on: [v0_assets_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_assets_order_by!] + + """filter the rows returned""" + where: v0_assets_bool_exp + ): [v0_assets!]! + + """An array relationship""" + blocks( + """distinct select on columns""" + distinct_on: [v0_blocks_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_blocks_order_by!] + + """filter the rows returned""" + where: v0_blocks_bool_exp + ): [v0_blocks!]! + chain_id: String! + display_name: String + enabled: Boolean + + """An array relationship""" + explorers( + """distinct select on columns""" + distinct_on: [v0_explorers_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_explorers_order_by!] + + """filter the rows returned""" + where: v0_explorers_bool_exp + ): [v0_explorers!]! + id: Int! + logo_uri: String + rpc_type: String + + """An array relationship""" + rpcs( + """distinct select on columns""" + distinct_on: [v0_rpcs_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_rpcs_order_by!] + + """filter the rows returned""" + where: v0_rpcs_bool_exp + ): [v0_rpcs!]! + testnet: Boolean + + """An array relationship""" + transactions( + """distinct select on columns""" + distinct_on: [v0_transactions_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transactions_order_by!] + + """filter the rows returned""" + where: v0_transactions_bool_exp + ): [v0_transactions!]! + + """An array relationship""" + ucs1_configurations( + """distinct select on columns""" + distinct_on: [v0_ucs1_configuration_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_ucs1_configuration_order_by!] + + """filter the rows returned""" + where: v0_ucs1_configuration_bool_exp + ): [v0_ucs1_configuration!]! +} + +""" +Boolean expression to filter rows from the table "v0.chains". All fields are combined with a logical 'AND'. +""" +input v0_chains_bool_exp { + _and: [v0_chains_bool_exp!] + _not: v0_chains_bool_exp + _or: [v0_chains_bool_exp!] + addr_prefix: String_comparison_exp + assets: v0_assets_bool_exp + blocks: v0_blocks_bool_exp + chain_id: String_comparison_exp + display_name: String_comparison_exp + enabled: Boolean_comparison_exp + explorers: v0_explorers_bool_exp + id: Int_comparison_exp + logo_uri: String_comparison_exp + rpc_type: String_comparison_exp + rpcs: v0_rpcs_bool_exp + testnet: Boolean_comparison_exp + transactions: v0_transactions_bool_exp + ucs1_configurations: v0_ucs1_configuration_bool_exp +} + +"""Ordering options when selecting data from "v0.chains".""" +input v0_chains_order_by { + addr_prefix: order_by + assets_aggregate: v0_assets_aggregate_order_by + blocks_aggregate: v0_blocks_aggregate_order_by + chain_id: order_by + display_name: order_by + enabled: order_by + explorers_aggregate: v0_explorers_aggregate_order_by + id: order_by + logo_uri: order_by + rpc_type: order_by + rpcs_aggregate: v0_rpcs_aggregate_order_by + testnet: order_by + transactions_aggregate: v0_transactions_aggregate_order_by + ucs1_configurations_aggregate: v0_ucs1_configuration_aggregate_order_by +} + +""" +select columns of table "v0.chains" +""" +enum v0_chains_select_column { + """column name""" + addr_prefix + + """column name""" + chain_id + + """column name""" + display_name + + """column name""" + enabled + + """column name""" + id + + """column name""" + logo_uri + + """column name""" + rpc_type + + """column name""" + testnet +} + +""" +Streaming cursor of the table "v0_chains" +""" +input v0_chains_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_chains_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_chains_stream_cursor_value_input { + addr_prefix: String + chain_id: String + display_name: String + enabled: Boolean + id: Int + logo_uri: String + rpc_type: String + testnet: Boolean +} + +""" +columns and relationships of "v0.channel_map" +""" +type v0_channel_map { + """An object relationship""" + connection: v0_connection_map + + """An object relationship""" + destination: v0_chains + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + + """An object relationship""" + source: v0_chains + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String +} + +""" +Boolean expression to filter rows from the table "v0.channel_map". All fields are combined with a logical 'AND'. +""" +input v0_channel_map_bool_exp { + _and: [v0_channel_map_bool_exp!] + _not: v0_channel_map_bool_exp + _or: [v0_channel_map_bool_exp!] + connection: v0_connection_map_bool_exp + destination: v0_chains_bool_exp + from_chain_id: String_comparison_exp + from_channel_id: String_comparison_exp + from_connection_id: String_comparison_exp + from_id: Int_comparison_exp + from_port_id: String_comparison_exp + source: v0_chains_bool_exp + status: String_comparison_exp + to_chain_id: String_comparison_exp + to_channel_id: String_comparison_exp + to_connection_id: String_comparison_exp + to_id: Int_comparison_exp + to_port_id: String_comparison_exp +} + +"""Ordering options when selecting data from "v0.channel_map".""" +input v0_channel_map_order_by { + connection: v0_connection_map_order_by + destination: v0_chains_order_by + from_chain_id: order_by + from_channel_id: order_by + from_connection_id: order_by + from_id: order_by + from_port_id: order_by + source: v0_chains_order_by + status: order_by + to_chain_id: order_by + to_channel_id: order_by + to_connection_id: order_by + to_id: order_by + to_port_id: order_by +} + +""" +select columns of table "v0.channel_map" +""" +enum v0_channel_map_select_column { + """column name""" + from_chain_id + + """column name""" + from_channel_id + + """column name""" + from_connection_id + + """column name""" + from_id + + """column name""" + from_port_id + + """column name""" + status + + """column name""" + to_chain_id + + """column name""" + to_channel_id + + """column name""" + to_connection_id + + """column name""" + to_id + + """column name""" + to_port_id +} + +""" +Streaming cursor of the table "v0_channel_map" +""" +input v0_channel_map_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_channel_map_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_channel_map_stream_cursor_value_input { + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String +} + +""" +columns and relationships of "v0.channels" +""" +type v0_channels { + """An object relationship""" + destination_chain: v0_chains + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + + """An object relationship""" + source_chain: v0_chains + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + status: String +} + +""" +aggregated selection of "v0.channels" +""" +type v0_channels_aggregate { + aggregate: v0_channels_aggregate_fields + nodes: [v0_channels!]! +} + +""" +aggregate fields of "v0.channels" +""" +type v0_channels_aggregate_fields { + avg: v0_channels_avg_fields + count(columns: [v0_channels_select_column!], distinct: Boolean): Int! + max: v0_channels_max_fields + min: v0_channels_min_fields + stddev: v0_channels_stddev_fields + stddev_pop: v0_channels_stddev_pop_fields + stddev_samp: v0_channels_stddev_samp_fields + sum: v0_channels_sum_fields + var_pop: v0_channels_var_pop_fields + var_samp: v0_channels_var_samp_fields + variance: v0_channels_variance_fields +} + +"""aggregate avg on columns""" +type v0_channels_avg_fields { + destination_chain_id: Float + source_chain_id: Float +} + +""" +Boolean expression to filter rows from the table "v0.channels". All fields are combined with a logical 'AND'. +""" +input v0_channels_bool_exp { + _and: [v0_channels_bool_exp!] + _not: v0_channels_bool_exp + _or: [v0_channels_bool_exp!] + destination_chain: v0_chains_bool_exp + destination_chain_id: Int_comparison_exp + destination_channel_id: String_comparison_exp + destination_connection_id: String_comparison_exp + destination_port_id: String_comparison_exp + source_chain: v0_chains_bool_exp + source_chain_id: Int_comparison_exp + source_channel_id: String_comparison_exp + source_connection_id: String_comparison_exp + source_port_id: String_comparison_exp + status: String_comparison_exp +} + +"""aggregate max on columns""" +type v0_channels_max_fields { + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + status: String +} + +"""aggregate min on columns""" +type v0_channels_min_fields { + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + status: String +} + +"""Ordering options when selecting data from "v0.channels".""" +input v0_channels_order_by { + destination_chain: v0_chains_order_by + destination_chain_id: order_by + destination_channel_id: order_by + destination_connection_id: order_by + destination_port_id: order_by + source_chain: v0_chains_order_by + source_chain_id: order_by + source_channel_id: order_by + source_connection_id: order_by + source_port_id: order_by + status: order_by +} + +""" +select columns of table "v0.channels" +""" +enum v0_channels_select_column { + """column name""" + destination_chain_id + + """column name""" + destination_channel_id + + """column name""" + destination_connection_id + + """column name""" + destination_port_id + + """column name""" + source_chain_id + + """column name""" + source_channel_id + + """column name""" + source_connection_id + + """column name""" + source_port_id + + """column name""" + status +} + +"""aggregate stddev on columns""" +type v0_channels_stddev_fields { + destination_chain_id: Float + source_chain_id: Float +} + +"""aggregate stddev_pop on columns""" +type v0_channels_stddev_pop_fields { + destination_chain_id: Float + source_chain_id: Float +} + +"""aggregate stddev_samp on columns""" +type v0_channels_stddev_samp_fields { + destination_chain_id: Float + source_chain_id: Float +} + +""" +Streaming cursor of the table "v0_channels" +""" +input v0_channels_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_channels_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_channels_stream_cursor_value_input { + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + status: String +} + +"""aggregate sum on columns""" +type v0_channels_sum_fields { + destination_chain_id: Int + source_chain_id: Int +} + +"""aggregate var_pop on columns""" +type v0_channels_var_pop_fields { + destination_chain_id: Float + source_chain_id: Float +} + +"""aggregate var_samp on columns""" +type v0_channels_var_samp_fields { + destination_chain_id: Float + source_chain_id: Float +} + +"""aggregate variance on columns""" +type v0_channels_variance_fields { + destination_chain_id: Float + source_chain_id: Float +} + +""" +columns and relationships of "v0.connection_map" +""" +type v0_connection_map { + """An object relationship""" + destination_chain: v0_chains + from_chain_id: String + from_client_id: String + from_connection_id: String + from_id: Int + + """An object relationship""" + source_chain: v0_chains + status: String + to_chain_id: String + to_client_id: String + to_connection_id: String + to_id: Int +} + +""" +Boolean expression to filter rows from the table "v0.connection_map". All fields are combined with a logical 'AND'. +""" +input v0_connection_map_bool_exp { + _and: [v0_connection_map_bool_exp!] + _not: v0_connection_map_bool_exp + _or: [v0_connection_map_bool_exp!] + destination_chain: v0_chains_bool_exp + from_chain_id: String_comparison_exp + from_client_id: String_comparison_exp + from_connection_id: String_comparison_exp + from_id: Int_comparison_exp + source_chain: v0_chains_bool_exp + status: String_comparison_exp + to_chain_id: String_comparison_exp + to_client_id: String_comparison_exp + to_connection_id: String_comparison_exp + to_id: Int_comparison_exp +} + +"""Ordering options when selecting data from "v0.connection_map".""" +input v0_connection_map_order_by { + destination_chain: v0_chains_order_by + from_chain_id: order_by + from_client_id: order_by + from_connection_id: order_by + from_id: order_by + source_chain: v0_chains_order_by + status: order_by + to_chain_id: order_by + to_client_id: order_by + to_connection_id: order_by + to_id: order_by +} + +""" +select columns of table "v0.connection_map" +""" +enum v0_connection_map_select_column { + """column name""" + from_chain_id + + """column name""" + from_client_id + + """column name""" + from_connection_id + + """column name""" + from_id + + """column name""" + status + + """column name""" + to_chain_id + + """column name""" + to_client_id + + """column name""" + to_connection_id + + """column name""" + to_id +} + +""" +Streaming cursor of the table "v0_connection_map" +""" +input v0_connection_map_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_connection_map_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_connection_map_stream_cursor_value_input { + from_chain_id: String + from_client_id: String + from_connection_id: String + from_id: Int + status: String + to_chain_id: String + to_client_id: String + to_connection_id: String + to_id: Int +} + +""" +columns and relationships of "v0.connections" +""" +type v0_connections { + destination_chain_id: Int + destination_client_id: String + destination_connection_id: String + source_chain_id: Int + source_client_id: String + source_connection_id: String + status: String +} + +""" +Boolean expression to filter rows from the table "v0.connections". All fields are combined with a logical 'AND'. +""" +input v0_connections_bool_exp { + _and: [v0_connections_bool_exp!] + _not: v0_connections_bool_exp + _or: [v0_connections_bool_exp!] + destination_chain_id: Int_comparison_exp + destination_client_id: String_comparison_exp + destination_connection_id: String_comparison_exp + source_chain_id: Int_comparison_exp + source_client_id: String_comparison_exp + source_connection_id: String_comparison_exp + status: String_comparison_exp +} + +"""Ordering options when selecting data from "v0.connections".""" +input v0_connections_order_by { + destination_chain_id: order_by + destination_client_id: order_by + destination_connection_id: order_by + source_chain_id: order_by + source_client_id: order_by + source_connection_id: order_by + status: order_by +} + +""" +select columns of table "v0.connections" +""" +enum v0_connections_select_column { + """column name""" + destination_chain_id + + """column name""" + destination_client_id + + """column name""" + destination_connection_id + + """column name""" + source_chain_id + + """column name""" + source_client_id + + """column name""" + source_connection_id + + """column name""" + status +} + +""" +Streaming cursor of the table "v0_connections" +""" +input v0_connections_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_connections_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_connections_stream_cursor_value_input { + destination_chain_id: Int + destination_client_id: String + destination_connection_id: String + source_chain_id: Int + source_client_id: String + source_connection_id: String + status: String +} + +""" +columns and relationships of "v0.daily_packets" +""" +type v0_daily_packets { + count: bigint + day: timestamptz +} + +""" +Boolean expression to filter rows from the table "v0.daily_packets". All fields are combined with a logical 'AND'. +""" +input v0_daily_packets_bool_exp { + _and: [v0_daily_packets_bool_exp!] + _not: v0_daily_packets_bool_exp + _or: [v0_daily_packets_bool_exp!] + count: bigint_comparison_exp + day: timestamptz_comparison_exp +} + +"""Ordering options when selecting data from "v0.daily_packets".""" +input v0_daily_packets_order_by { + count: order_by + day: order_by +} + +""" +select columns of table "v0.daily_packets" +""" +enum v0_daily_packets_select_column { + """column name""" + count + + """column name""" + day +} + +""" +Streaming cursor of the table "v0_daily_packets" +""" +input v0_daily_packets_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_daily_packets_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_daily_packets_stream_cursor_value_input { + count: bigint + day: timestamptz +} + +""" +columns and relationships of "v0.daily_transfers" +""" +type v0_daily_transfers { + count: bigint + day: timestamptz +} + +""" +Boolean expression to filter rows from the table "v0.daily_transfers". All fields are combined with a logical 'AND'. +""" +input v0_daily_transfers_bool_exp { + _and: [v0_daily_transfers_bool_exp!] + _not: v0_daily_transfers_bool_exp + _or: [v0_daily_transfers_bool_exp!] + count: bigint_comparison_exp + day: timestamptz_comparison_exp +} + +"""Ordering options when selecting data from "v0.daily_transfers".""" +input v0_daily_transfers_order_by { + count: order_by + day: order_by +} + +""" +select columns of table "v0.daily_transfers" +""" +enum v0_daily_transfers_select_column { + """column name""" + count + + """column name""" + day +} + +""" +Streaming cursor of the table "v0_daily_transfers" +""" +input v0_daily_transfers_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_daily_transfers_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_daily_transfers_stream_cursor_value_input { + count: bigint + day: timestamptz +} + +"""Blockchain explorers and their info.""" +type v0_explorers { + address_url: String! + block_url: String! + + """An object relationship""" + chain: v0_chains! + chain_id: Int! + description: String! + display_name: String! + home_url: String! + id: Int! + name: String! + tx_url: String! +} + +""" +order by aggregate values of table "v0.explorers" +""" +input v0_explorers_aggregate_order_by { + avg: v0_explorers_avg_order_by + count: order_by + max: v0_explorers_max_order_by + min: v0_explorers_min_order_by + stddev: v0_explorers_stddev_order_by + stddev_pop: v0_explorers_stddev_pop_order_by + stddev_samp: v0_explorers_stddev_samp_order_by + sum: v0_explorers_sum_order_by + var_pop: v0_explorers_var_pop_order_by + var_samp: v0_explorers_var_samp_order_by + variance: v0_explorers_variance_order_by +} + +""" +order by avg() on columns of table "v0.explorers" +""" +input v0_explorers_avg_order_by { + chain_id: order_by + id: order_by +} + +""" +Boolean expression to filter rows from the table "v0.explorers". All fields are combined with a logical 'AND'. +""" +input v0_explorers_bool_exp { + _and: [v0_explorers_bool_exp!] + _not: v0_explorers_bool_exp + _or: [v0_explorers_bool_exp!] + address_url: String_comparison_exp + block_url: String_comparison_exp + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + description: String_comparison_exp + display_name: String_comparison_exp + home_url: String_comparison_exp + id: Int_comparison_exp + name: String_comparison_exp + tx_url: String_comparison_exp +} + +""" +order by max() on columns of table "v0.explorers" +""" +input v0_explorers_max_order_by { + address_url: order_by + block_url: order_by + chain_id: order_by + description: order_by + display_name: order_by + home_url: order_by + id: order_by + name: order_by + tx_url: order_by +} + +""" +order by min() on columns of table "v0.explorers" +""" +input v0_explorers_min_order_by { + address_url: order_by + block_url: order_by + chain_id: order_by + description: order_by + display_name: order_by + home_url: order_by + id: order_by + name: order_by + tx_url: order_by +} + +"""Ordering options when selecting data from "v0.explorers".""" +input v0_explorers_order_by { + address_url: order_by + block_url: order_by + chain: v0_chains_order_by + chain_id: order_by + description: order_by + display_name: order_by + home_url: order_by + id: order_by + name: order_by + tx_url: order_by +} + +""" +select columns of table "v0.explorers" +""" +enum v0_explorers_select_column { + """column name""" + address_url + + """column name""" + block_url + + """column name""" + chain_id + + """column name""" + description + + """column name""" + display_name + + """column name""" + home_url + + """column name""" + id + + """column name""" + name + + """column name""" + tx_url +} + +""" +order by stddev() on columns of table "v0.explorers" +""" +input v0_explorers_stddev_order_by { + chain_id: order_by + id: order_by +} + +""" +order by stddev_pop() on columns of table "v0.explorers" +""" +input v0_explorers_stddev_pop_order_by { + chain_id: order_by + id: order_by +} + +""" +order by stddev_samp() on columns of table "v0.explorers" +""" +input v0_explorers_stddev_samp_order_by { + chain_id: order_by + id: order_by +} + +""" +Streaming cursor of the table "v0_explorers" +""" +input v0_explorers_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_explorers_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_explorers_stream_cursor_value_input { + address_url: String + block_url: String + chain_id: Int + description: String + display_name: String + home_url: String + id: Int + name: String + tx_url: String +} + +""" +order by sum() on columns of table "v0.explorers" +""" +input v0_explorers_sum_order_by { + chain_id: order_by + id: order_by +} + +""" +order by var_pop() on columns of table "v0.explorers" +""" +input v0_explorers_var_pop_order_by { + chain_id: order_by + id: order_by +} + +""" +order by var_samp() on columns of table "v0.explorers" +""" +input v0_explorers_var_samp_order_by { + chain_id: order_by + id: order_by +} + +""" +order by variance() on columns of table "v0.explorers" +""" +input v0_explorers_variance_order_by { + chain_id: order_by + id: order_by +} + +""" +columns and relationships of "v0.faucets" +""" +type v0_faucets { + chain_id: Int! + denom: String! + display_name: String! + enabled: Boolean! + url: String! +} + +""" +order by aggregate values of table "v0.faucets" +""" +input v0_faucets_aggregate_order_by { + avg: v0_faucets_avg_order_by + count: order_by + max: v0_faucets_max_order_by + min: v0_faucets_min_order_by + stddev: v0_faucets_stddev_order_by + stddev_pop: v0_faucets_stddev_pop_order_by + stddev_samp: v0_faucets_stddev_samp_order_by + sum: v0_faucets_sum_order_by + var_pop: v0_faucets_var_pop_order_by + var_samp: v0_faucets_var_samp_order_by + variance: v0_faucets_variance_order_by +} + +""" +order by avg() on columns of table "v0.faucets" +""" +input v0_faucets_avg_order_by { + chain_id: order_by +} + +""" +Boolean expression to filter rows from the table "v0.faucets". All fields are combined with a logical 'AND'. +""" +input v0_faucets_bool_exp { + _and: [v0_faucets_bool_exp!] + _not: v0_faucets_bool_exp + _or: [v0_faucets_bool_exp!] + chain_id: Int_comparison_exp + denom: String_comparison_exp + display_name: String_comparison_exp + enabled: Boolean_comparison_exp + url: String_comparison_exp +} + +""" +order by max() on columns of table "v0.faucets" +""" +input v0_faucets_max_order_by { + chain_id: order_by + denom: order_by + display_name: order_by + url: order_by +} + +""" +order by min() on columns of table "v0.faucets" +""" +input v0_faucets_min_order_by { + chain_id: order_by + denom: order_by + display_name: order_by + url: order_by +} + +"""Ordering options when selecting data from "v0.faucets".""" +input v0_faucets_order_by { + chain_id: order_by + denom: order_by + display_name: order_by + enabled: order_by + url: order_by +} + +""" +select columns of table "v0.faucets" +""" +enum v0_faucets_select_column { + """column name""" + chain_id + + """column name""" + denom + + """column name""" + display_name + + """column name""" + enabled + + """column name""" + url +} + +""" +order by stddev() on columns of table "v0.faucets" +""" +input v0_faucets_stddev_order_by { + chain_id: order_by +} + +""" +order by stddev_pop() on columns of table "v0.faucets" +""" +input v0_faucets_stddev_pop_order_by { + chain_id: order_by +} + +""" +order by stddev_samp() on columns of table "v0.faucets" +""" +input v0_faucets_stddev_samp_order_by { + chain_id: order_by +} + +""" +Streaming cursor of the table "v0_faucets" +""" +input v0_faucets_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_faucets_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_faucets_stream_cursor_value_input { + chain_id: Int + denom: String + display_name: String + enabled: Boolean + url: String +} + +""" +order by sum() on columns of table "v0.faucets" +""" +input v0_faucets_sum_order_by { + chain_id: order_by +} + +""" +order by var_pop() on columns of table "v0.faucets" +""" +input v0_faucets_var_pop_order_by { + chain_id: order_by +} + +""" +order by var_samp() on columns of table "v0.faucets" +""" +input v0_faucets_var_samp_order_by { + chain_id: order_by +} + +""" +order by variance() on columns of table "v0.faucets" +""" +input v0_faucets_variance_order_by { + chain_id: order_by +} + +input v0_get_transfer_forwards_args { + transfer: transfers_scalar +} + +""" +columns and relationships of "v0.index_status" +""" +type v0_index_status { + """An object relationship""" + chain: v0_chains + chain_id: String + display_name: String + height: Int + id: Int + status: String + timestamp: timestamptz + tip_age_seconds: numeric +} + +""" +Boolean expression to filter rows from the table "v0.index_status". All fields are combined with a logical 'AND'. +""" +input v0_index_status_bool_exp { + _and: [v0_index_status_bool_exp!] + _not: v0_index_status_bool_exp + _or: [v0_index_status_bool_exp!] + chain: v0_chains_bool_exp + chain_id: String_comparison_exp + display_name: String_comparison_exp + height: Int_comparison_exp + id: Int_comparison_exp + status: String_comparison_exp + timestamp: timestamptz_comparison_exp + tip_age_seconds: numeric_comparison_exp +} + +"""Ordering options when selecting data from "v0.index_status".""" +input v0_index_status_order_by { + chain: v0_chains_order_by + chain_id: order_by + display_name: order_by + height: order_by + id: order_by + status: order_by + timestamp: order_by + tip_age_seconds: order_by +} + +""" +select columns of table "v0.index_status" +""" +enum v0_index_status_select_column { + """column name""" + chain_id + + """column name""" + display_name + + """column name""" + height + + """column name""" + id + + """column name""" + status + + """column name""" + timestamp + + """column name""" + tip_age_seconds +} + +""" +Streaming cursor of the table "v0_index_status" +""" +input v0_index_status_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_index_status_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_index_status_stream_cursor_value_input { + chain_id: String + display_name: String + height: Int + id: Int + status: String + timestamp: timestamptz + tip_age_seconds: numeric +} + +""" +columns and relationships of "v0.packets" +""" +type v0_packets { + destination_block_hash: String + + """An object relationship""" + destination_chain: v0_chains + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_json( + """JSON select path""" + path: String + ): jsonb + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + source_block_hash: String + + """An object relationship""" + source_chain: v0_chains + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_json( + """JSON select path""" + path: String + ): jsonb + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String +} + +""" +aggregated selection of "v0.packets" +""" +type v0_packets_aggregate { + aggregate: v0_packets_aggregate_fields + nodes: [v0_packets!]! +} + +""" +aggregate fields of "v0.packets" +""" +type v0_packets_aggregate_fields { + avg: v0_packets_avg_fields + count(columns: [v0_packets_select_column!], distinct: Boolean): Int! + max: v0_packets_max_fields + min: v0_packets_min_fields + stddev: v0_packets_stddev_fields + stddev_pop: v0_packets_stddev_pop_fields + stddev_samp: v0_packets_stddev_samp_fields + sum: v0_packets_sum_fields + var_pop: v0_packets_var_pop_fields + var_samp: v0_packets_var_samp_fields + variance: v0_packets_variance_fields +} + +"""aggregate avg on columns""" +type v0_packets_avg_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +""" +Boolean expression to filter rows from the table "v0.packets". All fields are combined with a logical 'AND'. +""" +input v0_packets_bool_exp { + _and: [v0_packets_bool_exp!] + _not: v0_packets_bool_exp + _or: [v0_packets_bool_exp!] + destination_block_hash: String_comparison_exp + destination_chain: v0_chains_bool_exp + destination_chain_id: Int_comparison_exp + destination_channel: String_comparison_exp + destination_data: String_comparison_exp + destination_height: Int_comparison_exp + destination_json: jsonb_comparison_exp + destination_port: String_comparison_exp + destination_sequence: numeric_comparison_exp + destination_time: timestamptz_comparison_exp + destination_timeout_timestamp: numeric_comparison_exp + destination_transaction_hash: String_comparison_exp + destination_transaction_index: String_comparison_exp + source_block_hash: String_comparison_exp + source_chain: v0_chains_bool_exp + source_chain_id: Int_comparison_exp + source_channel: String_comparison_exp + source_data: String_comparison_exp + source_height: Int_comparison_exp + source_json: jsonb_comparison_exp + source_port: String_comparison_exp + source_sequence: numeric_comparison_exp + source_time: timestamptz_comparison_exp + source_timeout_timestamp: numeric_comparison_exp + source_transaction_hash: String_comparison_exp + source_transaction_index: String_comparison_exp + status: String_comparison_exp +} + +""" +columns and relationships of "v0.packets_mat" +""" +type v0_packets_mat { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_json( + """JSON select path""" + path: String + ): jsonb + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + pfm_memo: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_json( + """JSON select path""" + path: String + ): jsonb + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String + version: String +} + +""" +aggregated selection of "v0.packets_mat" +""" +type v0_packets_mat_aggregate { + aggregate: v0_packets_mat_aggregate_fields + nodes: [v0_packets_mat!]! +} + +""" +aggregate fields of "v0.packets_mat" +""" +type v0_packets_mat_aggregate_fields { + avg: v0_packets_mat_avg_fields + count(columns: [v0_packets_mat_select_column!], distinct: Boolean): Int! + max: v0_packets_mat_max_fields + min: v0_packets_mat_min_fields + stddev: v0_packets_mat_stddev_fields + stddev_pop: v0_packets_mat_stddev_pop_fields + stddev_samp: v0_packets_mat_stddev_samp_fields + sum: v0_packets_mat_sum_fields + var_pop: v0_packets_mat_var_pop_fields + var_samp: v0_packets_mat_var_samp_fields + variance: v0_packets_mat_variance_fields +} + +"""aggregate avg on columns""" +type v0_packets_mat_avg_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +""" +Boolean expression to filter rows from the table "v0.packets_mat". All fields are combined with a logical 'AND'. +""" +input v0_packets_mat_bool_exp { + _and: [v0_packets_mat_bool_exp!] + _not: v0_packets_mat_bool_exp + _or: [v0_packets_mat_bool_exp!] + destination_block_hash: String_comparison_exp + destination_chain_id: Int_comparison_exp + destination_channel: String_comparison_exp + destination_data: String_comparison_exp + destination_height: Int_comparison_exp + destination_json: jsonb_comparison_exp + destination_port: String_comparison_exp + destination_sequence: numeric_comparison_exp + destination_time: timestamptz_comparison_exp + destination_timeout_timestamp: numeric_comparison_exp + destination_transaction_hash: String_comparison_exp + destination_transaction_index: String_comparison_exp + from_chain_id: String_comparison_exp + from_channel_id: String_comparison_exp + from_connection_id: String_comparison_exp + from_id: Int_comparison_exp + from_port_id: String_comparison_exp + pfm_memo: String_comparison_exp + source_block_hash: String_comparison_exp + source_chain_id: Int_comparison_exp + source_channel: String_comparison_exp + source_data: String_comparison_exp + source_height: Int_comparison_exp + source_json: jsonb_comparison_exp + source_port: String_comparison_exp + source_sequence: numeric_comparison_exp + source_time: timestamptz_comparison_exp + source_timeout_timestamp: numeric_comparison_exp + source_transaction_hash: String_comparison_exp + source_transaction_index: String_comparison_exp + status: String_comparison_exp + to_chain_id: String_comparison_exp + to_channel_id: String_comparison_exp + to_connection_id: String_comparison_exp + to_id: Int_comparison_exp + to_port_id: String_comparison_exp + version: String_comparison_exp +} + +"""aggregate max on columns""" +type v0_packets_mat_max_fields { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + pfm_memo: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String + version: String +} + +"""aggregate min on columns""" +type v0_packets_mat_min_fields { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + pfm_memo: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String + version: String +} + +"""Ordering options when selecting data from "v0.packets_mat".""" +input v0_packets_mat_order_by { + destination_block_hash: order_by + destination_chain_id: order_by + destination_channel: order_by + destination_data: order_by + destination_height: order_by + destination_json: order_by + destination_port: order_by + destination_sequence: order_by + destination_time: order_by + destination_timeout_timestamp: order_by + destination_transaction_hash: order_by + destination_transaction_index: order_by + from_chain_id: order_by + from_channel_id: order_by + from_connection_id: order_by + from_id: order_by + from_port_id: order_by + pfm_memo: order_by + source_block_hash: order_by + source_chain_id: order_by + source_channel: order_by + source_data: order_by + source_height: order_by + source_json: order_by + source_port: order_by + source_sequence: order_by + source_time: order_by + source_timeout_timestamp: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by + to_chain_id: order_by + to_channel_id: order_by + to_connection_id: order_by + to_id: order_by + to_port_id: order_by + version: order_by +} + +""" +select columns of table "v0.packets_mat" +""" +enum v0_packets_mat_select_column { + """column name""" + destination_block_hash + + """column name""" + destination_chain_id + + """column name""" + destination_channel + + """column name""" + destination_data + + """column name""" + destination_height + + """column name""" + destination_json + + """column name""" + destination_port + + """column name""" + destination_sequence + + """column name""" + destination_time + + """column name""" + destination_timeout_timestamp + + """column name""" + destination_transaction_hash + + """column name""" + destination_transaction_index + + """column name""" + from_chain_id + + """column name""" + from_channel_id + + """column name""" + from_connection_id + + """column name""" + from_id + + """column name""" + from_port_id + + """column name""" + pfm_memo + + """column name""" + source_block_hash + + """column name""" + source_chain_id + + """column name""" + source_channel + + """column name""" + source_data + + """column name""" + source_height + + """column name""" + source_json + + """column name""" + source_port + + """column name""" + source_sequence + + """column name""" + source_time + + """column name""" + source_timeout_timestamp + + """column name""" + source_transaction_hash + + """column name""" + source_transaction_index + + """column name""" + status + + """column name""" + to_chain_id + + """column name""" + to_channel_id + + """column name""" + to_connection_id + + """column name""" + to_id + + """column name""" + to_port_id + + """column name""" + version +} + +"""aggregate stddev on columns""" +type v0_packets_mat_stddev_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +"""aggregate stddev_pop on columns""" +type v0_packets_mat_stddev_pop_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +"""aggregate stddev_samp on columns""" +type v0_packets_mat_stddev_samp_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +""" +Streaming cursor of the table "v0_packets_mat" +""" +input v0_packets_mat_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_packets_mat_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_packets_mat_stream_cursor_value_input { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_json: jsonb + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + from_chain_id: String + from_channel_id: String + from_connection_id: String + from_id: Int + from_port_id: String + pfm_memo: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_json: jsonb + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String + to_chain_id: String + to_channel_id: String + to_connection_id: String + to_id: Int + to_port_id: String + version: String +} + +"""aggregate sum on columns""" +type v0_packets_mat_sum_fields { + destination_chain_id: Int + destination_height: Int + destination_sequence: numeric + destination_timeout_timestamp: numeric + from_id: Int + source_chain_id: Int + source_height: Int + source_sequence: numeric + source_timeout_timestamp: numeric + to_id: Int +} + +"""aggregate var_pop on columns""" +type v0_packets_mat_var_pop_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +"""aggregate var_samp on columns""" +type v0_packets_mat_var_samp_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +"""aggregate variance on columns""" +type v0_packets_mat_variance_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + from_id: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float + to_id: Float +} + +"""aggregate max on columns""" +type v0_packets_max_fields { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String +} + +"""aggregate min on columns""" +type v0_packets_min_fields { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String +} + +"""Ordering options when selecting data from "v0.packets".""" +input v0_packets_order_by { + destination_block_hash: order_by + destination_chain: v0_chains_order_by + destination_chain_id: order_by + destination_channel: order_by + destination_data: order_by + destination_height: order_by + destination_json: order_by + destination_port: order_by + destination_sequence: order_by + destination_time: order_by + destination_timeout_timestamp: order_by + destination_transaction_hash: order_by + destination_transaction_index: order_by + source_block_hash: order_by + source_chain: v0_chains_order_by + source_chain_id: order_by + source_channel: order_by + source_data: order_by + source_height: order_by + source_json: order_by + source_port: order_by + source_sequence: order_by + source_time: order_by + source_timeout_timestamp: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by +} + +""" +select columns of table "v0.packets" +""" +enum v0_packets_select_column { + """column name""" + destination_block_hash + + """column name""" + destination_chain_id + + """column name""" + destination_channel + + """column name""" + destination_data + + """column name""" + destination_height + + """column name""" + destination_json + + """column name""" + destination_port + + """column name""" + destination_sequence + + """column name""" + destination_time + + """column name""" + destination_timeout_timestamp + + """column name""" + destination_transaction_hash + + """column name""" + destination_transaction_index + + """column name""" + source_block_hash + + """column name""" + source_chain_id + + """column name""" + source_channel + + """column name""" + source_data + + """column name""" + source_height + + """column name""" + source_json + + """column name""" + source_port + + """column name""" + source_sequence + + """column name""" + source_time + + """column name""" + source_timeout_timestamp + + """column name""" + source_transaction_hash + + """column name""" + source_transaction_index + + """column name""" + status +} + +"""aggregate stddev on columns""" +type v0_packets_stddev_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate stddev_pop on columns""" +type v0_packets_stddev_pop_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate stddev_samp on columns""" +type v0_packets_stddev_samp_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +""" +Streaming cursor of the table "v0_packets" +""" +input v0_packets_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_packets_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_packets_stream_cursor_value_input { + destination_block_hash: String + destination_chain_id: Int + destination_channel: String + destination_data: String + destination_height: Int + destination_json: jsonb + destination_port: String + destination_sequence: numeric + destination_time: timestamptz + destination_timeout_timestamp: numeric + destination_transaction_hash: String + destination_transaction_index: String + source_block_hash: String + source_chain_id: Int + source_channel: String + source_data: String + source_height: Int + source_json: jsonb + source_port: String + source_sequence: numeric + source_time: timestamptz + source_timeout_timestamp: numeric + source_transaction_hash: String + source_transaction_index: String + status: String +} + +"""aggregate sum on columns""" +type v0_packets_sum_fields { + destination_chain_id: Int + destination_height: Int + destination_sequence: numeric + destination_timeout_timestamp: numeric + source_chain_id: Int + source_height: Int + source_sequence: numeric + source_timeout_timestamp: numeric +} + +"""aggregate var_pop on columns""" +type v0_packets_var_pop_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate var_samp on columns""" +type v0_packets_var_samp_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate variance on columns""" +type v0_packets_variance_fields { + destination_chain_id: Float + destination_height: Float + destination_sequence: Float + destination_timeout_timestamp: Float + source_chain_id: Float + source_height: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""Various RPC endpoints for the different networks that Union supports. """ +type v0_rpcs { + """An object relationship""" + chain: v0_chains! + chain_id: Int! + description: String + enabled: Boolean! + type: String! + url: String! +} + +""" +order by aggregate values of table "v0.rpcs" +""" +input v0_rpcs_aggregate_order_by { + avg: v0_rpcs_avg_order_by + count: order_by + max: v0_rpcs_max_order_by + min: v0_rpcs_min_order_by + stddev: v0_rpcs_stddev_order_by + stddev_pop: v0_rpcs_stddev_pop_order_by + stddev_samp: v0_rpcs_stddev_samp_order_by + sum: v0_rpcs_sum_order_by + var_pop: v0_rpcs_var_pop_order_by + var_samp: v0_rpcs_var_samp_order_by + variance: v0_rpcs_variance_order_by +} + +""" +order by avg() on columns of table "v0.rpcs" +""" +input v0_rpcs_avg_order_by { + chain_id: order_by +} + +""" +Boolean expression to filter rows from the table "v0.rpcs". All fields are combined with a logical 'AND'. +""" +input v0_rpcs_bool_exp { + _and: [v0_rpcs_bool_exp!] + _not: v0_rpcs_bool_exp + _or: [v0_rpcs_bool_exp!] + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + description: String_comparison_exp + enabled: Boolean_comparison_exp + type: String_comparison_exp + url: String_comparison_exp +} + +""" +order by max() on columns of table "v0.rpcs" +""" +input v0_rpcs_max_order_by { + chain_id: order_by + description: order_by + type: order_by + url: order_by +} + +""" +order by min() on columns of table "v0.rpcs" +""" +input v0_rpcs_min_order_by { + chain_id: order_by + description: order_by + type: order_by + url: order_by +} + +"""Ordering options when selecting data from "v0.rpcs".""" +input v0_rpcs_order_by { + chain: v0_chains_order_by + chain_id: order_by + description: order_by + enabled: order_by + type: order_by + url: order_by +} + +""" +select columns of table "v0.rpcs" +""" +enum v0_rpcs_select_column { + """column name""" + chain_id + + """column name""" + description + + """column name""" + enabled + + """column name""" + type + + """column name""" + url +} + +""" +order by stddev() on columns of table "v0.rpcs" +""" +input v0_rpcs_stddev_order_by { + chain_id: order_by +} + +""" +order by stddev_pop() on columns of table "v0.rpcs" +""" +input v0_rpcs_stddev_pop_order_by { + chain_id: order_by +} + +""" +order by stddev_samp() on columns of table "v0.rpcs" +""" +input v0_rpcs_stddev_samp_order_by { + chain_id: order_by +} + +""" +Streaming cursor of the table "v0_rpcs" +""" +input v0_rpcs_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_rpcs_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_rpcs_stream_cursor_value_input { + chain_id: Int + description: String + enabled: Boolean + type: String + url: String +} + +""" +order by sum() on columns of table "v0.rpcs" +""" +input v0_rpcs_sum_order_by { + chain_id: order_by +} + +""" +order by var_pop() on columns of table "v0.rpcs" +""" +input v0_rpcs_var_pop_order_by { + chain_id: order_by +} + +""" +order by var_samp() on columns of table "v0.rpcs" +""" +input v0_rpcs_var_samp_order_by { + chain_id: order_by +} + +""" +order by variance() on columns of table "v0.rpcs" +""" +input v0_rpcs_variance_order_by { + chain_id: order_by +} + +""" +columns and relationships of "v0.traces" +""" +type v0_traces { + """An object relationship""" + chain: v0_chains + chain_id: Int + data( + """JSON select path""" + path: String + ): jsonb + height: bigint + initiating_transaction_hash: String + timestamp: timestamptz + transaction_hash: String + + """An object relationship""" + transfer: v0_transfers + type: String +} + +""" +order by aggregate values of table "v0.traces" +""" +input v0_traces_aggregate_order_by { + avg: v0_traces_avg_order_by + count: order_by + max: v0_traces_max_order_by + min: v0_traces_min_order_by + stddev: v0_traces_stddev_order_by + stddev_pop: v0_traces_stddev_pop_order_by + stddev_samp: v0_traces_stddev_samp_order_by + sum: v0_traces_sum_order_by + var_pop: v0_traces_var_pop_order_by + var_samp: v0_traces_var_samp_order_by + variance: v0_traces_variance_order_by +} + +""" +order by avg() on columns of table "v0.traces" +""" +input v0_traces_avg_order_by { + chain_id: order_by + height: order_by +} + +""" +Boolean expression to filter rows from the table "v0.traces". All fields are combined with a logical 'AND'. +""" +input v0_traces_bool_exp { + _and: [v0_traces_bool_exp!] + _not: v0_traces_bool_exp + _or: [v0_traces_bool_exp!] + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + data: jsonb_comparison_exp + height: bigint_comparison_exp + initiating_transaction_hash: String_comparison_exp + timestamp: timestamptz_comparison_exp + transaction_hash: String_comparison_exp + transfer: v0_transfers_bool_exp + type: String_comparison_exp +} + +""" +order by max() on columns of table "v0.traces" +""" +input v0_traces_max_order_by { + chain_id: order_by + height: order_by + initiating_transaction_hash: order_by + timestamp: order_by + transaction_hash: order_by + type: order_by +} + +""" +order by min() on columns of table "v0.traces" +""" +input v0_traces_min_order_by { + chain_id: order_by + height: order_by + initiating_transaction_hash: order_by + timestamp: order_by + transaction_hash: order_by + type: order_by +} + +"""Ordering options when selecting data from "v0.traces".""" +input v0_traces_order_by { + chain: v0_chains_order_by + chain_id: order_by + data: order_by + height: order_by + initiating_transaction_hash: order_by + timestamp: order_by + transaction_hash: order_by + transfer: v0_transfers_order_by + type: order_by +} + +""" +select columns of table "v0.traces" +""" +enum v0_traces_select_column { + """column name""" + chain_id + + """column name""" + data + + """column name""" + height + + """column name""" + initiating_transaction_hash + + """column name""" + timestamp + + """column name""" + transaction_hash + + """column name""" + type +} + +""" +order by stddev() on columns of table "v0.traces" +""" +input v0_traces_stddev_order_by { + chain_id: order_by + height: order_by +} + +""" +order by stddev_pop() on columns of table "v0.traces" +""" +input v0_traces_stddev_pop_order_by { + chain_id: order_by + height: order_by +} + +""" +order by stddev_samp() on columns of table "v0.traces" +""" +input v0_traces_stddev_samp_order_by { + chain_id: order_by + height: order_by +} + +""" +Streaming cursor of the table "v0_traces" +""" +input v0_traces_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_traces_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_traces_stream_cursor_value_input { + chain_id: Int + data: jsonb + height: bigint + initiating_transaction_hash: String + timestamp: timestamptz + transaction_hash: String + type: String +} + +""" +order by sum() on columns of table "v0.traces" +""" +input v0_traces_sum_order_by { + chain_id: order_by + height: order_by +} + +""" +order by var_pop() on columns of table "v0.traces" +""" +input v0_traces_var_pop_order_by { + chain_id: order_by + height: order_by +} + +""" +order by var_samp() on columns of table "v0.traces" +""" +input v0_traces_var_samp_order_by { + chain_id: order_by + height: order_by +} + +""" +order by variance() on columns of table "v0.traces" +""" +input v0_traces_variance_order_by { + chain_id: order_by + height: order_by +} + +""" +columns and relationships of "v0.transactions" +""" +type v0_transactions { + """An object relationship""" + block: v0_blocks + block_hash: String! + + """An object relationship""" + chain: v0_chains! + chain_id: Int! + data( + """JSON select path""" + path: String + ): jsonb! + hash: String! + height: Int! + index: Int! + + """SUCCESS if the transaction succeeded, FAILED otherwise.""" + status( + """ + input parameters for computed field "status" defined on table "v0.transactions" + """ + args: status_v0_transactions_args! + ): String +} + +""" +order by aggregate values of table "v0.transactions" +""" +input v0_transactions_aggregate_order_by { + avg: v0_transactions_avg_order_by + count: order_by + max: v0_transactions_max_order_by + min: v0_transactions_min_order_by + stddev: v0_transactions_stddev_order_by + stddev_pop: v0_transactions_stddev_pop_order_by + stddev_samp: v0_transactions_stddev_samp_order_by + sum: v0_transactions_sum_order_by + var_pop: v0_transactions_var_pop_order_by + var_samp: v0_transactions_var_samp_order_by + variance: v0_transactions_variance_order_by +} + +""" +order by avg() on columns of table "v0.transactions" +""" +input v0_transactions_avg_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +Boolean expression to filter rows from the table "v0.transactions". All fields are combined with a logical 'AND'. +""" +input v0_transactions_bool_exp { + _and: [v0_transactions_bool_exp!] + _not: v0_transactions_bool_exp + _or: [v0_transactions_bool_exp!] + block: v0_blocks_bool_exp + block_hash: String_comparison_exp + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + data: jsonb_comparison_exp + hash: String_comparison_exp + height: Int_comparison_exp + index: Int_comparison_exp +} + +""" +order by max() on columns of table "v0.transactions" +""" +input v0_transactions_max_order_by { + block_hash: order_by + chain_id: order_by + hash: order_by + height: order_by + index: order_by +} + +""" +order by min() on columns of table "v0.transactions" +""" +input v0_transactions_min_order_by { + block_hash: order_by + chain_id: order_by + hash: order_by + height: order_by + index: order_by +} + +"""Ordering options when selecting data from "v0.transactions".""" +input v0_transactions_order_by { + block: v0_blocks_order_by + block_hash: order_by + chain: v0_chains_order_by + chain_id: order_by + data: order_by + hash: order_by + height: order_by + index: order_by +} + +""" +select columns of table "v0.transactions" +""" +enum v0_transactions_select_column { + """column name""" + block_hash + + """column name""" + chain_id + + """column name""" + data + + """column name""" + hash + + """column name""" + height + + """column name""" + index +} + +""" +order by stddev() on columns of table "v0.transactions" +""" +input v0_transactions_stddev_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +order by stddev_pop() on columns of table "v0.transactions" +""" +input v0_transactions_stddev_pop_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +order by stddev_samp() on columns of table "v0.transactions" +""" +input v0_transactions_stddev_samp_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +Streaming cursor of the table "v0_transactions" +""" +input v0_transactions_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_transactions_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_transactions_stream_cursor_value_input { + block_hash: String + chain_id: Int + data: jsonb + hash: String + height: Int + index: Int +} + +""" +order by sum() on columns of table "v0.transactions" +""" +input v0_transactions_sum_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +order by var_pop() on columns of table "v0.transactions" +""" +input v0_transactions_var_pop_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +order by var_samp() on columns of table "v0.transactions" +""" +input v0_transactions_var_samp_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +order by variance() on columns of table "v0.transactions" +""" +input v0_transactions_variance_order_by { + chain_id: order_by + height: order_by + index: order_by +} + +""" +columns and relationships of "v0.transfer_forwards" +""" +type v0_transfer_forwards { + """An object relationship""" + chain: v0_chains + chain_id: Int + channel: String + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + port: String + receiver: String + retries: String + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + source_transaction_hash: String + source_transaction_index: String + status: String + timeout: String + version: String +} + +""" +order by aggregate values of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_aggregate_order_by { + avg: v0_transfer_forwards_avg_order_by + count: order_by + max: v0_transfer_forwards_max_order_by + min: v0_transfer_forwards_min_order_by + stddev: v0_transfer_forwards_stddev_order_by + stddev_pop: v0_transfer_forwards_stddev_pop_order_by + stddev_samp: v0_transfer_forwards_stddev_samp_order_by + sum: v0_transfer_forwards_sum_order_by + var_pop: v0_transfer_forwards_var_pop_order_by + var_samp: v0_transfer_forwards_var_samp_order_by + variance: v0_transfer_forwards_variance_order_by +} + +""" +order by avg() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_avg_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +Boolean expression to filter rows from the table "v0.transfer_forwards". All fields are combined with a logical 'AND'. +""" +input v0_transfer_forwards_bool_exp { + _and: [v0_transfer_forwards_bool_exp!] + _not: v0_transfer_forwards_bool_exp + _or: [v0_transfer_forwards_bool_exp!] + chain: v0_chains_bool_exp + chain_id: Int_comparison_exp + channel: String_comparison_exp + destination_chain_id: Int_comparison_exp + destination_channel_id: String_comparison_exp + destination_connection_id: String_comparison_exp + destination_port_id: String_comparison_exp + port: String_comparison_exp + receiver: String_comparison_exp + retries: String_comparison_exp + source_chain_id: Int_comparison_exp + source_channel_id: String_comparison_exp + source_connection_id: String_comparison_exp + source_port_id: String_comparison_exp + source_transaction_hash: String_comparison_exp + source_transaction_index: String_comparison_exp + status: String_comparison_exp + timeout: String_comparison_exp + version: String_comparison_exp +} + +""" +order by max() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_max_order_by { + chain_id: order_by + channel: order_by + destination_chain_id: order_by + destination_channel_id: order_by + destination_connection_id: order_by + destination_port_id: order_by + port: order_by + receiver: order_by + retries: order_by + source_chain_id: order_by + source_channel_id: order_by + source_connection_id: order_by + source_port_id: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by + timeout: order_by + version: order_by +} + +""" +order by min() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_min_order_by { + chain_id: order_by + channel: order_by + destination_chain_id: order_by + destination_channel_id: order_by + destination_connection_id: order_by + destination_port_id: order_by + port: order_by + receiver: order_by + retries: order_by + source_chain_id: order_by + source_channel_id: order_by + source_connection_id: order_by + source_port_id: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by + timeout: order_by + version: order_by +} + +"""Ordering options when selecting data from "v0.transfer_forwards".""" +input v0_transfer_forwards_order_by { + chain: v0_chains_order_by + chain_id: order_by + channel: order_by + destination_chain_id: order_by + destination_channel_id: order_by + destination_connection_id: order_by + destination_port_id: order_by + port: order_by + receiver: order_by + retries: order_by + source_chain_id: order_by + source_channel_id: order_by + source_connection_id: order_by + source_port_id: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by + timeout: order_by + version: order_by +} + +""" +select columns of table "v0.transfer_forwards" +""" +enum v0_transfer_forwards_select_column { + """column name""" + chain_id + + """column name""" + channel + + """column name""" + destination_chain_id + + """column name""" + destination_channel_id + + """column name""" + destination_connection_id + + """column name""" + destination_port_id + + """column name""" + port + + """column name""" + receiver + + """column name""" + retries + + """column name""" + source_chain_id + + """column name""" + source_channel_id + + """column name""" + source_connection_id + + """column name""" + source_port_id + + """column name""" + source_transaction_hash + + """column name""" + source_transaction_index + + """column name""" + status + + """column name""" + timeout + + """column name""" + version +} + +""" +order by stddev() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_stddev_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by stddev_pop() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_stddev_pop_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by stddev_samp() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_stddev_samp_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +Streaming cursor of the table "v0_transfer_forwards" +""" +input v0_transfer_forwards_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_transfer_forwards_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_transfer_forwards_stream_cursor_value_input { + chain_id: Int + channel: String + destination_chain_id: Int + destination_channel_id: String + destination_connection_id: String + destination_port_id: String + port: String + receiver: String + retries: String + source_chain_id: Int + source_channel_id: String + source_connection_id: String + source_port_id: String + source_transaction_hash: String + source_transaction_index: String + status: String + timeout: String + version: String +} + +""" +order by sum() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_sum_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by var_pop() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_var_pop_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by var_samp() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_var_samp_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by variance() on columns of table "v0.transfer_forwards" +""" +input v0_transfer_forwards_variance_order_by { + chain_id: order_by + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +columns and relationships of "v0.transfers" +""" +type v0_transfers { + assets( + """JSON select path""" + path: String + ): jsonb + destination_block_hash: String + + """An object relationship""" + destination_chain: v0_chains + destination_chain_id: String + destination_channel_id: String + destination_connection_id: String + destination_data: String + destination_height: Int + destination_id: Int + destination_json( + """JSON select path""" + path: String + ): jsonb + destination_port: String + destination_sequence: numeric + destination_timeout_timestamp: numeric + destination_timestamp: timestamptz + destination_transaction_hash: String + destination_transaction_index: String + + """An array relationship""" + forwards( + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!]! + + """ + A computed field, executes function "v0.get_transfer_forwards" + """ + forwards_2( + """distinct select on columns""" + distinct_on: [v0_transfer_forwards_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_transfer_forwards_order_by!] + + """filter the rows returned""" + where: v0_transfer_forwards_bool_exp + ): [v0_transfer_forwards!] + + """An object relationship""" + hop: v0_transfers + is_initiating: Boolean + normalized_receiver: String + normalized_sender: String + packet_data_jsonb( + """JSON select path""" + path: String + ): jsonb + pfm_destination_channel: String + pfm_destination_port: String + pfm_recv_sequence: Int + pfm_sent_sequence: Int + pfm_source_channel: String + pfm_source_port: String + receiver: String + sender: String + source_block_hash: String + + """An object relationship""" + source_chain: v0_chains + source_chain_id: String + source_channel_id: String + source_connection_id: String + source_data: String + source_height: Int + source_id: Int + source_json( + """JSON select path""" + path: String + ): jsonb + source_port: String + source_sequence: numeric + source_timeout_timestamp: numeric + source_timestamp: timestamptz + source_transaction_hash: String + source_transaction_index: String + status: String + + """An array relationship""" + traces( + """distinct select on columns""" + distinct_on: [v0_traces_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_traces_order_by!] + + """filter the rows returned""" + where: v0_traces_bool_exp + ): [v0_traces!]! + transaction_hash: String +} + +""" +aggregated selection of "v0.transfers" +""" +type v0_transfers_aggregate { + aggregate: v0_transfers_aggregate_fields + nodes: [v0_transfers!]! +} + +""" +aggregate fields of "v0.transfers" +""" +type v0_transfers_aggregate_fields { + avg: v0_transfers_avg_fields + count(columns: [v0_transfers_select_column!], distinct: Boolean): Int! + max: v0_transfers_max_fields + min: v0_transfers_min_fields + stddev: v0_transfers_stddev_fields + stddev_pop: v0_transfers_stddev_pop_fields + stddev_samp: v0_transfers_stddev_samp_fields + sum: v0_transfers_sum_fields + var_pop: v0_transfers_var_pop_fields + var_samp: v0_transfers_var_samp_fields + variance: v0_transfers_variance_fields +} + +"""aggregate avg on columns""" +type v0_transfers_avg_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +""" +Boolean expression to filter rows from the table "v0.transfers". All fields are combined with a logical 'AND'. +""" +input v0_transfers_bool_exp { + _and: [v0_transfers_bool_exp!] + _not: v0_transfers_bool_exp + _or: [v0_transfers_bool_exp!] + assets: jsonb_comparison_exp + destination_block_hash: String_comparison_exp + destination_chain: v0_chains_bool_exp + destination_chain_id: String_comparison_exp + destination_channel_id: String_comparison_exp + destination_connection_id: String_comparison_exp + destination_data: String_comparison_exp + destination_height: Int_comparison_exp + destination_id: Int_comparison_exp + destination_json: jsonb_comparison_exp + destination_port: String_comparison_exp + destination_sequence: numeric_comparison_exp + destination_timeout_timestamp: numeric_comparison_exp + destination_timestamp: timestamptz_comparison_exp + destination_transaction_hash: String_comparison_exp + destination_transaction_index: String_comparison_exp + forwards: v0_transfer_forwards_bool_exp + forwards_2: v0_transfer_forwards_bool_exp + hop: v0_transfers_bool_exp + is_initiating: Boolean_comparison_exp + normalized_receiver: String_comparison_exp + normalized_sender: String_comparison_exp + packet_data_jsonb: jsonb_comparison_exp + pfm_destination_channel: String_comparison_exp + pfm_destination_port: String_comparison_exp + pfm_recv_sequence: Int_comparison_exp + pfm_sent_sequence: Int_comparison_exp + pfm_source_channel: String_comparison_exp + pfm_source_port: String_comparison_exp + receiver: String_comparison_exp + sender: String_comparison_exp + source_block_hash: String_comparison_exp + source_chain: v0_chains_bool_exp + source_chain_id: String_comparison_exp + source_channel_id: String_comparison_exp + source_connection_id: String_comparison_exp + source_data: String_comparison_exp + source_height: Int_comparison_exp + source_id: Int_comparison_exp + source_json: jsonb_comparison_exp + source_port: String_comparison_exp + source_sequence: numeric_comparison_exp + source_timeout_timestamp: numeric_comparison_exp + source_timestamp: timestamptz_comparison_exp + source_transaction_hash: String_comparison_exp + source_transaction_index: String_comparison_exp + status: String_comparison_exp + traces: v0_traces_bool_exp + transaction_hash: String_comparison_exp +} + +"""aggregate max on columns""" +type v0_transfers_max_fields { + destination_block_hash: String + destination_chain_id: String + destination_channel_id: String + destination_connection_id: String + destination_data: String + destination_height: Int + destination_id: Int + destination_port: String + destination_sequence: numeric + destination_timeout_timestamp: numeric + destination_timestamp: timestamptz + destination_transaction_hash: String + destination_transaction_index: String + normalized_receiver: String + normalized_sender: String + pfm_destination_channel: String + pfm_destination_port: String + pfm_recv_sequence: Int + pfm_sent_sequence: Int + pfm_source_channel: String + pfm_source_port: String + receiver: String + sender: String + source_block_hash: String + source_chain_id: String + source_channel_id: String + source_connection_id: String + source_data: String + source_height: Int + source_id: Int + source_port: String + source_sequence: numeric + source_timeout_timestamp: numeric + source_timestamp: timestamptz + source_transaction_hash: String + source_transaction_index: String + status: String + transaction_hash: String +} + +"""aggregate min on columns""" +type v0_transfers_min_fields { + destination_block_hash: String + destination_chain_id: String + destination_channel_id: String + destination_connection_id: String + destination_data: String + destination_height: Int + destination_id: Int + destination_port: String + destination_sequence: numeric + destination_timeout_timestamp: numeric + destination_timestamp: timestamptz + destination_transaction_hash: String + destination_transaction_index: String + normalized_receiver: String + normalized_sender: String + pfm_destination_channel: String + pfm_destination_port: String + pfm_recv_sequence: Int + pfm_sent_sequence: Int + pfm_source_channel: String + pfm_source_port: String + receiver: String + sender: String + source_block_hash: String + source_chain_id: String + source_channel_id: String + source_connection_id: String + source_data: String + source_height: Int + source_id: Int + source_port: String + source_sequence: numeric + source_timeout_timestamp: numeric + source_timestamp: timestamptz + source_transaction_hash: String + source_transaction_index: String + status: String + transaction_hash: String +} + +"""Ordering options when selecting data from "v0.transfers".""" +input v0_transfers_order_by { + assets: order_by + destination_block_hash: order_by + destination_chain: v0_chains_order_by + destination_chain_id: order_by + destination_channel_id: order_by + destination_connection_id: order_by + destination_data: order_by + destination_height: order_by + destination_id: order_by + destination_json: order_by + destination_port: order_by + destination_sequence: order_by + destination_timeout_timestamp: order_by + destination_timestamp: order_by + destination_transaction_hash: order_by + destination_transaction_index: order_by + forwards_2_aggregate: v0_transfer_forwards_aggregate_order_by + forwards_aggregate: v0_transfer_forwards_aggregate_order_by + hop: v0_transfers_order_by + is_initiating: order_by + normalized_receiver: order_by + normalized_sender: order_by + packet_data_jsonb: order_by + pfm_destination_channel: order_by + pfm_destination_port: order_by + pfm_recv_sequence: order_by + pfm_sent_sequence: order_by + pfm_source_channel: order_by + pfm_source_port: order_by + receiver: order_by + sender: order_by + source_block_hash: order_by + source_chain: v0_chains_order_by + source_chain_id: order_by + source_channel_id: order_by + source_connection_id: order_by + source_data: order_by + source_height: order_by + source_id: order_by + source_json: order_by + source_port: order_by + source_sequence: order_by + source_timeout_timestamp: order_by + source_timestamp: order_by + source_transaction_hash: order_by + source_transaction_index: order_by + status: order_by + traces_aggregate: v0_traces_aggregate_order_by + transaction_hash: order_by +} + +""" +select columns of table "v0.transfers" +""" +enum v0_transfers_select_column { + """column name""" + assets + + """column name""" + destination_block_hash + + """column name""" + destination_chain_id + + """column name""" + destination_channel_id + + """column name""" + destination_connection_id + + """column name""" + destination_data + + """column name""" + destination_height + + """column name""" + destination_id + + """column name""" + destination_json + + """column name""" + destination_port + + """column name""" + destination_sequence + + """column name""" + destination_timeout_timestamp + + """column name""" + destination_timestamp + + """column name""" + destination_transaction_hash + + """column name""" + destination_transaction_index + + """column name""" + is_initiating + + """column name""" + normalized_receiver + + """column name""" + normalized_sender + + """column name""" + packet_data_jsonb + + """column name""" + pfm_destination_channel + + """column name""" + pfm_destination_port + + """column name""" + pfm_recv_sequence + + """column name""" + pfm_sent_sequence + + """column name""" + pfm_source_channel + + """column name""" + pfm_source_port + + """column name""" + receiver + + """column name""" + sender + + """column name""" + source_block_hash + + """column name""" + source_chain_id + + """column name""" + source_channel_id + + """column name""" + source_connection_id + + """column name""" + source_data + + """column name""" + source_height + + """column name""" + source_id + + """column name""" + source_json + + """column name""" + source_port + + """column name""" + source_sequence + + """column name""" + source_timeout_timestamp + + """column name""" + source_timestamp + + """column name""" + source_transaction_hash + + """column name""" + source_transaction_index + + """column name""" + status + + """column name""" + transaction_hash +} + +"""aggregate stddev on columns""" +type v0_transfers_stddev_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate stddev_pop on columns""" +type v0_transfers_stddev_pop_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate stddev_samp on columns""" +type v0_transfers_stddev_samp_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +""" +Streaming cursor of the table "v0_transfers" +""" +input v0_transfers_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_transfers_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_transfers_stream_cursor_value_input { + assets: jsonb + destination_block_hash: String + destination_chain_id: String + destination_channel_id: String + destination_connection_id: String + destination_data: String + destination_height: Int + destination_id: Int + destination_json: jsonb + destination_port: String + destination_sequence: numeric + destination_timeout_timestamp: numeric + destination_timestamp: timestamptz + destination_transaction_hash: String + destination_transaction_index: String + is_initiating: Boolean + normalized_receiver: String + normalized_sender: String + packet_data_jsonb: jsonb + pfm_destination_channel: String + pfm_destination_port: String + pfm_recv_sequence: Int + pfm_sent_sequence: Int + pfm_source_channel: String + pfm_source_port: String + receiver: String + sender: String + source_block_hash: String + source_chain_id: String + source_channel_id: String + source_connection_id: String + source_data: String + source_height: Int + source_id: Int + source_json: jsonb + source_port: String + source_sequence: numeric + source_timeout_timestamp: numeric + source_timestamp: timestamptz + source_transaction_hash: String + source_transaction_index: String + status: String + transaction_hash: String +} + +"""aggregate sum on columns""" +type v0_transfers_sum_fields { + destination_height: Int + destination_id: Int + destination_sequence: numeric + destination_timeout_timestamp: numeric + pfm_recv_sequence: Int + pfm_sent_sequence: Int + source_height: Int + source_id: Int + source_sequence: numeric + source_timeout_timestamp: numeric +} + +"""aggregate var_pop on columns""" +type v0_transfers_var_pop_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate var_samp on columns""" +type v0_transfers_var_samp_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +"""aggregate variance on columns""" +type v0_transfers_variance_fields { + destination_height: Float + destination_id: Float + destination_sequence: Float + destination_timeout_timestamp: Float + pfm_recv_sequence: Float + pfm_sent_sequence: Float + source_height: Float + source_id: Float + source_sequence: Float + source_timeout_timestamp: Float +} + +""" +columns and relationships of "v0.ucs1_configuration" +""" +type v0_ucs1_configuration { + channel_id: String! + connection_id: String! + contract_address: String! + + """An object relationship""" + destination_chain: v0_chains! + destination_chain_id: Int! + + """An array relationship""" + forward( + """distinct select on columns""" + distinct_on: [v0_ucs1_configuration_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [v0_ucs1_configuration_order_by!] + + """filter the rows returned""" + where: v0_ucs1_configuration_bool_exp + ): [v0_ucs1_configuration!]! + port: String! + + """An object relationship""" + source_chain: v0_chains! + source_chain_id: Int! +} + +""" +order by aggregate values of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_aggregate_order_by { + avg: v0_ucs1_configuration_avg_order_by + count: order_by + max: v0_ucs1_configuration_max_order_by + min: v0_ucs1_configuration_min_order_by + stddev: v0_ucs1_configuration_stddev_order_by + stddev_pop: v0_ucs1_configuration_stddev_pop_order_by + stddev_samp: v0_ucs1_configuration_stddev_samp_order_by + sum: v0_ucs1_configuration_sum_order_by + var_pop: v0_ucs1_configuration_var_pop_order_by + var_samp: v0_ucs1_configuration_var_samp_order_by + variance: v0_ucs1_configuration_variance_order_by +} + +""" +order by avg() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_avg_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +Boolean expression to filter rows from the table "v0.ucs1_configuration". All fields are combined with a logical 'AND'. +""" +input v0_ucs1_configuration_bool_exp { + _and: [v0_ucs1_configuration_bool_exp!] + _not: v0_ucs1_configuration_bool_exp + _or: [v0_ucs1_configuration_bool_exp!] + channel_id: String_comparison_exp + connection_id: String_comparison_exp + contract_address: String_comparison_exp + destination_chain: v0_chains_bool_exp + destination_chain_id: Int_comparison_exp + forward: v0_ucs1_configuration_bool_exp + port: String_comparison_exp + source_chain: v0_chains_bool_exp + source_chain_id: Int_comparison_exp +} + +""" +order by max() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_max_order_by { + channel_id: order_by + connection_id: order_by + contract_address: order_by + destination_chain_id: order_by + port: order_by + source_chain_id: order_by +} + +""" +order by min() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_min_order_by { + channel_id: order_by + connection_id: order_by + contract_address: order_by + destination_chain_id: order_by + port: order_by + source_chain_id: order_by +} + +"""Ordering options when selecting data from "v0.ucs1_configuration".""" +input v0_ucs1_configuration_order_by { + channel_id: order_by + connection_id: order_by + contract_address: order_by + destination_chain: v0_chains_order_by + destination_chain_id: order_by + forward_aggregate: v0_ucs1_configuration_aggregate_order_by + port: order_by + source_chain: v0_chains_order_by + source_chain_id: order_by +} + +""" +select columns of table "v0.ucs1_configuration" +""" +enum v0_ucs1_configuration_select_column { + """column name""" + channel_id + + """column name""" + connection_id + + """column name""" + contract_address + + """column name""" + destination_chain_id + + """column name""" + port + + """column name""" + source_chain_id +} + +""" +order by stddev() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_stddev_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by stddev_pop() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_stddev_pop_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by stddev_samp() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_stddev_samp_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +Streaming cursor of the table "v0_ucs1_configuration" +""" +input v0_ucs1_configuration_stream_cursor_input { + """Stream column input with initial value""" + initial_value: v0_ucs1_configuration_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input v0_ucs1_configuration_stream_cursor_value_input { + channel_id: String + connection_id: String + contract_address: String + destination_chain_id: Int + port: String + source_chain_id: Int +} + +""" +order by sum() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_sum_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by var_pop() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_var_pop_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by var_samp() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_var_samp_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + +""" +order by variance() on columns of table "v0.ucs1_configuration" +""" +input v0_ucs1_configuration_variance_order_by { + destination_chain_id: order_by + source_chain_id: order_by +} + diff --git a/sentinel/src/args.rs b/sentinel/src/args.rs new file mode 100644 index 0000000000..95ee5081e6 --- /dev/null +++ b/sentinel/src/args.rs @@ -0,0 +1,63 @@ +use core::{fmt::Display, str::FromStr}; + +use clap::{Args, Parser, Subcommand}; +use regex::Regex; +use serde::Deserialize; + +#[derive(Clone, Parser)] +#[command(version, about, long_about = None)] +/// End-to-end tests and production monitoring scenarios to ensure Union is fully functional. +pub struct Cli { + /// Command to run. + #[command(subcommand)] + pub cmd: Command, +} + +#[derive(Clone, Subcommand)] +pub enum Command { + Info(InfoCmd), + Run(RunCmd), +} + +/// Display info about varios sentinels. +#[derive(Clone, Args)] +pub struct InfoCmd {} + +/// Run the sentinel testsuite. +#[derive(Clone, Args)] +pub struct RunCmd { + /// Configuration overrides for each individual Sentinel. Pass as an object of key value pairs, where each key is + /// the name of the sentinel. + #[arg(short, long, default_value_t)] + pub overrides: Overrides, + + /// Regex which matches sentinel names. All successful matches will be run. + #[arg(short, long)] + pub filter: Option, +} + +#[derive(Clone, Default, Deserialize)] +#[serde(transparent)] +pub struct Overrides { + inner: serde_json::Map, +} + +impl Display for Overrides { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "{}", serde_json::to_string(&self.inner).unwrap()) + } +} + +impl Overrides { + pub fn get(&self, key: &str) -> Option<&serde_json::Value> { + self.inner.get(key) + } +} + +impl FromStr for Overrides { + type Err = serde_json::Error; + + fn from_str(s: &str) -> Result { + serde_json::from_str(s) + } +} diff --git a/sentinel/src/main.rs b/sentinel/src/main.rs new file mode 100644 index 0000000000..64588eee82 --- /dev/null +++ b/sentinel/src/main.rs @@ -0,0 +1,78 @@ +mod args; +mod report; +mod runner; +mod sentinel; +mod sentinels; + +use std::process::ExitCode; + +use clap::Parser; + +use crate::{ + args::{Cli, Command}, + sentinel::Sentinel, +}; + +#[tokio::main] +async fn main() -> ExitCode { + let cli = Cli::parse(); + + tracing_subscriber::fmt().init(); + + let tests: Vec> = vec![ + Box::new(sentinels::fetch_latest_transfers::FetchLatestTransfers::default()), + Box::new(sentinels::check_ibc_trace_latency::CheckIbcTraceLatency::default()), + ]; + + let mut exit = ExitCode::SUCCESS; + + match cli.cmd { + Command::Info(_) => tests.iter().for_each(|test| { + println!("{} - {}", test.name(), test.description()); + }), + Command::Run(cmd) => { + let tests: Vec> = tests + .into_iter() + .map(|mut test| { + test.configure(&cmd); + test as Box + }) + .filter(|test| { + if let Some(filter) = &cmd.filter { + filter.captures(test.name()).is_some() + } else { + true + } + }) + .collect(); + + if tests.is_empty() { + println!("no tests to run, exiting."); + return ExitCode::SUCCESS; + } + + let reports = runner::run(None, tests).await; + + let mut failed = 0; + let mut ok = 0; + reports.into_iter().for_each(|report| { + if report.result.is_err() { + exit = ExitCode::FAILURE; + failed += 1; + } else { + ok += 1; + } + println!("{}", report) + }); + + let outcome = if failed == 0 { "passed" } else { "failed" }; + + println!(); + println!( + "sentinel result: {}. {} passed; {} failed;", + outcome, ok, failed + ); + } + } + exit +} diff --git a/sentinel/src/report.rs b/sentinel/src/report.rs new file mode 100644 index 0000000000..4eadd28b63 --- /dev/null +++ b/sentinel/src/report.rs @@ -0,0 +1,22 @@ +use core::fmt::Display; + +pub struct Report { + pub name: String, + pub result: anyhow::Result<()>, +} + +impl Report { + pub fn new(name: impl Into, result: anyhow::Result<()>) -> Self { + let name = name.into(); + Self { name, result } + } +} + +impl Display for Report { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match &self.result { + Ok(()) => write!(f, "sentinel {} ... ok", self.name), + Err(err) => write!(f, "sentinel {} ... FAILED\n {:?}", self.name, err), + } + } +} diff --git a/sentinel/src/runner.rs b/sentinel/src/runner.rs new file mode 100644 index 0000000000..8a5e52cc16 --- /dev/null +++ b/sentinel/src/runner.rs @@ -0,0 +1,27 @@ +use futures::stream::{self, StreamExt}; +use tracing::{info_span, Instrument}; + +use crate::{report::Report, sentinel::Sentinel}; + +pub async fn run( + limit: impl Into>, + sentinels: Vec>, +) -> Vec { + let max = sentinels.len(); + + stream::iter(sentinels.into_iter()) + .map(|mut sentinel| { + let name = sentinel.name(); + let span = info_span!("sentinel", name); + + async move { + sentinel.setup().instrument(span.clone()).await; + sentinel.run().instrument(span.clone()).await; + sentinel.teardown().instrument(span).await; + sentinel.report() + } + }) + .buffered(limit.into().unwrap_or(max)) + .collect() + .await +} diff --git a/sentinel/src/sentinel.rs b/sentinel/src/sentinel.rs new file mode 100644 index 0000000000..50c63acd05 --- /dev/null +++ b/sentinel/src/sentinel.rs @@ -0,0 +1,27 @@ +use async_trait::async_trait; + +use crate::{args::RunCmd, report::Report}; +/// A sentinel is a test scenario that is run against different production-like environments, +/// such as a local devnet, testnet, or even mainnet. +/// +/// Each Sentinel should require as little configuration as possible. If possible, fetch configurations +/// from the graphql API, secrets from a 1Password, as if this is a pure user interaction. +#[async_trait] +pub trait Sentinel: Send + Sync { + fn name(&self) -> &str; + + fn description(&self) -> &str; + + /// Perform any necessary test set up. This may be used to fetch data or perform one-time setup. Note that + /// as little IO as possible should be performed here. Querying for balances, RPC nodes through graphql.union.build, + /// or other operations that the UI might normally perform should occur in `Sentinel::run`. + async fn setup(&mut self) {} + + async fn run(&mut self); + + async fn teardown(&mut self) {} + + fn report(&mut self) -> Report; + + fn configure(&mut self, args: &RunCmd); +} diff --git a/sentinel/src/sentinels/check_ibc_trace_latency.rs b/sentinel/src/sentinels/check_ibc_trace_latency.rs new file mode 100644 index 0000000000..c1b2b4e92c --- /dev/null +++ b/sentinel/src/sentinels/check_ibc_trace_latency.rs @@ -0,0 +1,176 @@ +#![allow(non_camel_case_types)] + +use core::time::Duration; + +use anyhow::{anyhow, Result}; +use async_trait::async_trait; +use chrono::prelude::*; +use either::Either; +use graphql_client::{GraphQLQuery, Response}; +use json_value_merge::Merge; +use serde::{Deserialize, Serialize}; +use tokio::time::timeout; +use tracing::{error, info}; +use url::Url; + +use crate::{args::RunCmd, report::Report, sentinel::Sentinel}; + +type timestamptz = chrono::DateTime; + +#[derive(Serialize, Deserialize)] +pub struct CheckIbcTraceLatency { + /// The number of iterations or the timestamp to check until. + #[serde(with = "either::serde_untagged")] + pub until: Either>, + + /// The number of transfers to check per iteration. + pub limit: i64, + + /// The url of the graphql endpoint. + pub url: Url, + + /// The timeout per fetch request. + pub timeout: Duration, + + #[serde(skip_serializing, skip_deserializing, default)] + client: Option, + #[serde(skip_serializing, skip_deserializing, default)] + report: Option, +} + +impl CheckIbcTraceLatency { + async fn try_run(&self) -> Result<()> { + let client = self.client.clone().unwrap_or_default(); + + let mut source_time = Utc::now(); + let end_time = self + .until + .right() + .unwrap_or(DateTime::::from_timestamp(0, 0).unwrap()); + let end_iter = self.until.left().unwrap_or(usize::MAX); + + for _ in 0..end_iter { + if source_time > end_time { + break; + } + + let variables = last_transfers_with_traces::Variables { + source_time, + limit: self.limit, + }; + let body = LastTransfersWithTraces::build_query(variables); + + info!("fetching last {} transfers with traces", self.limit); + let raw = timeout( + self.timeout, + client.post(self.url.clone()).json(&body).send(), + ) + .await + .inspect_err(|err| { + error!( + "fetching transfers exceeded {:?} deadline: {}", + self.timeout, err + ); + })? + .inspect_err(|err| { + error!("fetching transfers failed: {}", err); + })? + .text() + .await?; + + let response: Response = + serde_json::from_str(&raw).inspect_err(|err| { + error!("decoding transfers failed: {}\n{}", err, raw); + })?; + + let transfers = response + .data + .ok_or(anyhow!("response data is empty"))? + .v0_transfers; + + for transfer in transfers { + for _trace in transfer.traces { + todo!( + " + - if time difference between different stages is too big, emit warning. + - if a stage is absent, emit error. + - if the transfer isn't finished, and the time delta between now and the stage + is greater than some limit, emit warning + " + ); + } + source_time = transfer.source_timestamp.unwrap(); + } + } + Ok(()) + } +} + +impl Default for CheckIbcTraceLatency { + fn default() -> Self { + CheckIbcTraceLatency { + until: Either::Left(3), + limit: 50, + timeout: Duration::from_secs(3), + url: Url::parse("https://graphql.union.build/v1/graphql").unwrap(), + client: Some(reqwest::Client::new()), + report: None, + } + } +} + +#[async_trait] +impl Sentinel for CheckIbcTraceLatency { + fn name(&self) -> &str { + "check_ibc_trace_latency" + } + + fn description(&self) -> &str { + "fetches the latest n transfers checks the time delta between each trace." + } + + async fn run(&mut self) { + let result = self.try_run().await; + self.report = Some(Report::new(self.name(), result)); + } + + fn report(&mut self) -> Report { + self.report.take().unwrap() + } + + fn configure(&mut self, args: &RunCmd) { + #![allow(clippy::needless_borrows_for_generic_args)] + let name = self.name(); + + if let Some(override_) = args.overrides.get(name) { + let mut me = serde_json::to_value(&self) + .expect("FetchLatestTransfers should be serializable to JSON"); + me.merge(override_); + let mut me: Self = serde_json::from_value(me) + .expect("FetchLatestTransfers should be deserializable from JSON"); + std::mem::swap(self, &mut me); + } + } +} + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "schema.graphql", + query_path = "queries.graphql", + response_derives = "Debug" +)] +pub struct LastTransfersWithTraces; + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_check_ibc_trace_latency_works() { + let mut sentinel = CheckIbcTraceLatency::default(); + sentinel.try_run().await.expect(&format!( + "checking last {} transfers and traces should work", + sentinel.limit + )); + } +} diff --git a/sentinel/src/sentinels/fetch_latest_transfers.rs b/sentinel/src/sentinels/fetch_latest_transfers.rs new file mode 100644 index 0000000000..f9c9a5b5e2 --- /dev/null +++ b/sentinel/src/sentinels/fetch_latest_transfers.rs @@ -0,0 +1,138 @@ +#![allow(non_camel_case_types)] +use std::time::Duration; + +use anyhow::{bail, Result}; +use async_trait::async_trait; +use graphql_client::{GraphQLQuery, Response}; +use json_value_merge::Merge; +use serde::{Deserialize, Serialize}; +use tokio::time::timeout; +use tracing::{error, info}; +use url::Url; + +use crate::{args::RunCmd, report::Report, sentinel::Sentinel}; + +/// A sentinel which checks that the last n transfers are fetchable within a given time. +#[derive(Serialize, Deserialize)] +pub struct FetchLatestTransfers { + /// The number of transfers to fetch. + pub limit: i64, + /// The url of the graphql endpoint. + pub url: Url, + /// The request timeout. If the request cannot be completed within the + /// duration, the test is considered failed. + pub timeout: Duration, + + #[serde(skip_serializing, skip_deserializing, default)] + client: Option, + #[serde(skip_serializing, skip_deserializing, default)] + report: Option, +} + +impl Default for FetchLatestTransfers { + fn default() -> Self { + FetchLatestTransfers { + limit: 50, + timeout: Duration::from_secs(3), + url: Url::parse("https://graphql.union.build/v1/graphql").unwrap(), + client: Some(reqwest::Client::new()), + report: None, + } + } +} + +type timestamptz = String; +type numeric = u128; +type jsonb = serde_json::Value; + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "schema.graphql", + query_path = "queries.graphql", + response_derives = "Debug" +)] +pub struct LastTransfersLimit; + +impl FetchLatestTransfers { + async fn try_run(&self) -> Result<()> { + let client = self.client.clone().unwrap_or_default(); + let variables = last_transfers_limit::Variables { limit: self.limit }; + let body = LastTransfersLimit::build_query(variables); + + info!("fetching last {} transfers", self.limit); + let raw = timeout( + self.timeout, + client.post(self.url.clone()).json(&body).send(), + ) + .await + .inspect_err(|err| { + error!( + "fetching transfers exceeded {:?} deadline: {}", + self.timeout, err + ); + })? + .inspect_err(|err| { + error!("fetching transfers failed: {}", err); + })? + .text() + .await?; + + let response: Response = serde_json::from_str(&raw) + .inspect_err(|err| { + error!("decoding transfers failed: {}\n{}", err, raw); + })?; + + if response.data.is_none() { + bail!("response had no data: {:?}", response) + } + Ok(()) + } +} + +#[async_trait] +impl Sentinel for FetchLatestTransfers { + fn name(&self) -> &str { + "fetch_latest_transfers" + } + + fn description(&self) -> &str { + "fetches the latest n transfers and times the request." + } + + async fn run(&mut self) { + let result = self.try_run().await; + self.report = Some(Report::new(self.name(), result)); + } + + fn report(&mut self) -> Report { + self.report.take().unwrap() + } + + fn configure(&mut self, args: &RunCmd) { + #![allow(clippy::needless_borrows_for_generic_args)] + let name = self.name(); + + if let Some(override_) = args.overrides.get(name) { + let mut me = serde_json::to_value(&self) + .expect("FetchLatestTransfers should be serializable to JSON"); + me.merge(override_); + let mut me: Self = serde_json::from_value(me) + .expect("FetchLatestTransfers should be deserializable from JSON"); + std::mem::swap(self, &mut me); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_fetch_latest_transfers_works() { + let mut sentinel = FetchLatestTransfers::default(); + sentinel.try_run().await.expect(&format!( + "fetching last {} transfers should work", + sentinel.limit + )); + } +} diff --git a/sentinel/src/sentinels/mod.rs b/sentinel/src/sentinels/mod.rs new file mode 100644 index 0000000000..cb96d7bbc4 --- /dev/null +++ b/sentinel/src/sentinels/mod.rs @@ -0,0 +1,2 @@ +pub mod check_ibc_trace_latency; +pub mod fetch_latest_transfers;