diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2ab770f..1fad2de 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,7 +3,7 @@ name: Build and Push Docker Image on: push: branches: - - main + - "*" jobs: docker: diff --git a/.sqlx/query-02a6ff6e2f997a5a57b5b35c416a45ce7917d4110a4a17bf24c637c7338ed9dd.json b/.sqlx/query-02a6ff6e2f997a5a57b5b35c416a45ce7917d4110a4a17bf24c637c7338ed9dd.json new file mode 100644 index 0000000..a949e88 --- /dev/null +++ b/.sqlx/query-02a6ff6e2f997a5a57b5b35c416a45ce7917d4110a4a17bf24c637c7338ed9dd.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n builder_pubkey,\n builder_name,\n uncensored_blocks,\n total_blocks\n FROM\n builder_blocks_30d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "builder_pubkey", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "builder_name", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "uncensored_blocks", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "total_blocks", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + true, + true, + true + ] + }, + "hash": "02a6ff6e2f997a5a57b5b35c416a45ce7917d4110a4a17bf24c637c7338ed9dd" +} diff --git a/.sqlx/query-02dc1734de68f766241196b5a33bc99cefb4379e1a9b4a099ea705b30e7bfbe0.json b/.sqlx/query-02dc1734de68f766241196b5a33bc99cefb4379e1a9b4a099ea705b30e7bfbe0.json new file mode 100644 index 0000000..ba682bf --- /dev/null +++ b/.sqlx/query-02dc1734de68f766241196b5a33bc99cefb4379e1a9b4a099ea705b30e7bfbe0.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n pubkey,\n builder_name\n FROM\n builder_pubkeys\n WHERE\n pubkey = ANY($1)\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "pubkey", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "builder_name", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "TextArray" + ] + }, + "nullable": [ + false, + true + ] + }, + "hash": "02dc1734de68f766241196b5a33bc99cefb4379e1a9b4a099ea705b30e7bfbe0" +} diff --git a/.sqlx/query-0cfa774a2cce1f084fa5cff3d3ee5631dbec2198bdb23b8eab7ab0d5f68e586f.json b/.sqlx/query-0cfa774a2cce1f084fa5cff3d3ee5631dbec2198bdb23b8eab7ab0d5f68e586f.json new file mode 100644 index 0000000..ad12a5b --- /dev/null +++ b/.sqlx/query-0cfa774a2cce1f084fa5cff3d3ee5631dbec2198bdb23b8eab7ab0d5f68e586f.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT slot_number\n FROM block_production\n ORDER BY slot_number ASC\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot_number", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false + ] + }, + "hash": "0cfa774a2cce1f084fa5cff3d3ee5631dbec2198bdb23b8eab7ab0d5f68e586f" +} diff --git a/.sqlx/query-1621984623036a1f8fc5be4f23153f975a134660297e4ec48c3f828d85ea4cfa.json b/.sqlx/query-1621984623036a1f8fc5be4f23153f975a134660297e4ec48c3f828d85ea4cfa.json new file mode 100644 index 0000000..91b4b27 --- /dev/null +++ b/.sqlx/query-1621984623036a1f8fc5be4f23153f975a134660297e4ec48c3f828d85ea4cfa.json @@ -0,0 +1,58 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n *\nFROM\n (\n SELECT\n transactions_data.transaction_hash,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.block_number,\n transactions_data.blocksdelay as block_delay,\n CASE\n WHEN blacklist = '{NULL}' THEN '{}'::text[]\n ELSE blacklist\n END AS blacklist,\n CASE\n WHEN transactions_data.low_balance = 1 THEN 'likely_insufficient_balance'\n WHEN transactions_data.lowbasefee = 1 THEN 'lowbasefee'\n WHEN transactions_data.lowtip = 1 THEN 'lowtip'\n WHEN transactions_data.congested = 1 THEN 'congested'\n WHEN transactions_data.blacklist != '{NULL}' THEN 'ofac'\n ELSE 'unknown'\n END AS reason\n FROM\n transactions_data\n WHERE\n transactions_data.mined > (CURRENT_DATE - $1::interval)\n AND transactions_data.blocksdelay > 1\n ) sq\nWHERE\n reason = 'ofac'\n OR reason = 'unknown'\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "transaction_hash", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "mined", + "type_info": "Timestamptz" + }, + { + "ordinal": 2, + "name": "delay", + "type_info": "Float8" + }, + { + "ordinal": 3, + "name": "block_number", + "type_info": "Int8" + }, + { + "ordinal": 4, + "name": "block_delay", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "blacklist", + "type_info": "TextArray" + }, + { + "ordinal": 6, + "name": "reason", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Interval" + ] + }, + "nullable": [ + false, + false, + null, + false, + false, + null, + null + ] + }, + "hash": "1621984623036a1f8fc5be4f23153f975a134660297e4ec48c3f828d85ea4cfa" +} diff --git a/.sqlx/query-18ea2228ecb0e48afe3ba2abdaa352bb8af24d3ebda29ffbae56fa5f97426479.json b/.sqlx/query-18ea2228ecb0e48afe3ba2abdaa352bb8af24d3ebda29ffbae56fa5f97426479.json new file mode 100644 index 0000000..934fa33 --- /dev/null +++ b/.sqlx/query-18ea2228ecb0e48afe3ba2abdaa352bb8af24d3ebda29ffbae56fa5f97426479.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n COALESCE(censored_tx_count, 0) AS censored_tx_count,\n COALESCE(censored_avg_delay, 0) AS censored_avg_delay,\n COALESCE(uncensored_tx_count, 0) AS uncensored_tx_count,\n COALESCE(uncensored_avg_delay, 0) AS uncensored_avg_delay\n FROM\n censorship_delay_7d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "censored_tx_count", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "censored_avg_delay", + "type_info": "Float8" + }, + { + "ordinal": 2, + "name": "uncensored_tx_count", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "uncensored_avg_delay", + "type_info": "Float8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null, + null, + null + ] + }, + "hash": "18ea2228ecb0e48afe3ba2abdaa352bb8af24d3ebda29ffbae56fa5f97426479" +} diff --git a/.sqlx/query-2f1fb67525b8bf6dc46897f153f4784a247d5575336d37dab6c9ece41b6effc7.json b/.sqlx/query-2f1fb67525b8bf6dc46897f153f4784a247d5575336d37dab6c9ece41b6effc7.json new file mode 100644 index 0000000..f2def60 --- /dev/null +++ b/.sqlx/query-2f1fb67525b8bf6dc46897f153f4784a247d5575336d37dab6c9ece41b6effc7.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO block_production (slot_number, block_number, block_hash, builder_pubkey, proposer_pubkey, relays, value)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (slot_number, block_number, block_hash)\n DO UPDATE SET\n relays = ARRAY (SELECT DISTINCT UNNEST(block_production.relays || $6)),\n value = $7\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Varchar", + "Varchar", + "Varchar", + "TextArray", + "Numeric" + ] + }, + "nullable": [] + }, + "hash": "2f1fb67525b8bf6dc46897f153f4784a247d5575336d37dab6c9ece41b6effc7" +} diff --git a/.sqlx/query-3b46131f6339a8f8f12f3bfc6e4e2a511f86c45a2ec6b38495cb3cb046b616e1.json b/.sqlx/query-3b46131f6339a8f8f12f3bfc6e4e2a511f86c45a2ec6b38495cb3cb046b616e1.json new file mode 100644 index 0000000..dff4273 --- /dev/null +++ b/.sqlx/query-3b46131f6339a8f8f12f3bfc6e4e2a511f86c45a2ec6b38495cb3cb046b616e1.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT timestamp\n FROM monitor_checkpoints\n WHERE monitor_id = $1\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "timestamp", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "3b46131f6339a8f8f12f3bfc6e4e2a511f86c45a2ec6b38495cb3cb046b616e1" +} diff --git a/.sqlx/query-42a5b7e42b58c30dd938249b7deed8ce306ab50c376ddc94a50c221249785709.json b/.sqlx/query-42a5b7e42b58c30dd938249b7deed8ce306ab50c376ddc94a50c221249785709.json new file mode 100644 index 0000000..c948d79 --- /dev/null +++ b/.sqlx/query-42a5b7e42b58c30dd938249b7deed8ce306ab50c376ddc94a50c221249785709.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n relay_id,\n total_blocks,\n uncensored_blocks\n FROM\n relay_censorship_7d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "relay_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "total_blocks", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "uncensored_blocks", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + true, + true + ] + }, + "hash": "42a5b7e42b58c30dd938249b7deed8ce306ab50c376ddc94a50c221249785709" +} diff --git a/.sqlx/query-4edb1b52690629a38cb7d5030f4fd98267a2af5496e2a03ac63535a715f8e7b0.json b/.sqlx/query-4edb1b52690629a38cb7d5030f4fd98267a2af5496e2a03ac63535a715f8e7b0.json new file mode 100644 index 0000000..2282e8d --- /dev/null +++ b/.sqlx/query-4edb1b52690629a38cb7d5030f4fd98267a2af5496e2a03ac63535a715f8e7b0.json @@ -0,0 +1,59 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n transactions_data.transaction_hash,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.block_number,\n transactions_data.blocksdelay as block_delay,\n CASE\n WHEN blacklist = '{NULL}' THEN '{}'::text[]\n ELSE blacklist\n END AS blacklist,\n CASE\n WHEN transactions_data.low_balance = 1 THEN 'likely_insufficient_balance'\n WHEN transactions_data.lowbasefee = 1 THEN 'lowbasefee'\n WHEN transactions_data.lowtip = 1 THEN 'lowtip'\n WHEN transactions_data.congested = 1 THEN 'congested'\n WHEN transactions_data.blacklist != '{NULL}' THEN 'ofac'\n ELSE 'unknown'\n END AS reason\n FROM\n transactions_data\n WHERE\n transactions_data.mined > (CURRENT_DATE - $1::interval)\n AND transactions_data.blocksdelay > 1\n ORDER BY\n transactions_data.mined DESC\n LIMIT $2\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "transaction_hash", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "mined", + "type_info": "Timestamptz" + }, + { + "ordinal": 2, + "name": "delay", + "type_info": "Float8" + }, + { + "ordinal": 3, + "name": "block_number", + "type_info": "Int8" + }, + { + "ordinal": 4, + "name": "block_delay", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "blacklist", + "type_info": "TextArray" + }, + { + "ordinal": 6, + "name": "reason", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Interval", + "Int8" + ] + }, + "nullable": [ + false, + false, + null, + false, + false, + null, + null + ] + }, + "hash": "4edb1b52690629a38cb7d5030f4fd98267a2af5496e2a03ac63535a715f8e7b0" +} diff --git a/.sqlx/query-4fe072ed2dc31c6239efa122c1f9087e50d4e76499f52d4f79befe04fd80317e.json b/.sqlx/query-4fe072ed2dc31c6239efa122c1f9087e50d4e76499f52d4f79befe04fd80317e.json new file mode 100644 index 0000000..e97a7db --- /dev/null +++ b/.sqlx/query-4fe072ed2dc31c6239efa122c1f9087e50d4e76499f52d4f79befe04fd80317e.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n bid as builder_id,\n COALESCE(censoring_pubkeys, 0) AS censoring_pubkeys,\n COALESCE(total_pubkeys, 0) AS total_pubkeys,\n COALESCE(number_of_blocks, 0) AS block_count\n FROM\n builders_7d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "builder_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "censoring_pubkeys", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "total_pubkeys", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "block_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + null, + null, + null + ] + }, + "hash": "4fe072ed2dc31c6239efa122c1f9087e50d4e76499f52d4f79befe04fd80317e" +} diff --git a/.sqlx/query-57e76c5f66376b4f6afed09b85f259ff0111a950e9da769b5804f91129246705.json b/.sqlx/query-57e76c5f66376b4f6afed09b85f259ff0111a950e9da769b5804f91129246705.json new file mode 100644 index 0000000..4b5117d --- /dev/null +++ b/.sqlx/query-57e76c5f66376b4f6afed09b85f259ff0111a950e9da769b5804f91129246705.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO monitor_checkpoints (monitor_id, timestamp)\n VALUES ($1, $2)\n ON CONFLICT (monitor_id) DO UPDATE SET timestamp = $2\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Timestamptz" + ] + }, + "nullable": [] + }, + "hash": "57e76c5f66376b4f6afed09b85f259ff0111a950e9da769b5804f91129246705" +} diff --git a/.sqlx/query-60c76c079e46f42a1cfbe737ea246d56d1bb3984470677da3cbe3260e2a29d7c.json b/.sqlx/query-60c76c079e46f42a1cfbe737ea246d56d1bb3984470677da3cbe3260e2a29d7c.json new file mode 100644 index 0000000..202ce86 --- /dev/null +++ b/.sqlx/query-60c76c079e46f42a1cfbe737ea246d56d1bb3984470677da3cbe3260e2a29d7c.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n UNNEST(relays) AS relay_id,\n COUNT(*) AS block_count,\n SUM(value / array_length(relays, 1)) / 10^18 AS total_value,\n AVG(value / array_length(relays, 1)) / 10^18 AS avg_value\n FROM\n block_production\n WHERE\n inserted_at >= NOW() - $1::interval\n GROUP BY\n relay_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "relay_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "block_count", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "total_value", + "type_info": "Float8" + }, + { + "ordinal": 3, + "name": "avg_value", + "type_info": "Float8" + } + ], + "parameters": { + "Left": [ + "Interval" + ] + }, + "nullable": [ + null, + null, + null, + null + ] + }, + "hash": "60c76c079e46f42a1cfbe737ea246d56d1bb3984470677da3cbe3260e2a29d7c" +} diff --git a/.sqlx/query-6f2ba37d7de520fbbbea680170556ffee644e58264a09f768c5feba34f8a7577.json b/.sqlx/query-6f2ba37d7de520fbbbea680170556ffee644e58264a09f768c5feba34f8a7577.json new file mode 100644 index 0000000..743d539 --- /dev/null +++ b/.sqlx/query-6f2ba37d7de520fbbbea680170556ffee644e58264a09f768c5feba34f8a7577.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n relay_id,\n total_blocks,\n uncensored_blocks\n FROM\n relay_censorship_30d\n\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "relay_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "total_blocks", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "uncensored_blocks", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + true, + true + ] + }, + "hash": "6f2ba37d7de520fbbbea680170556ffee644e58264a09f768c5feba34f8a7577" +} diff --git a/.sqlx/query-83992c141a7a1b6de48753c971d88915a117b585bcfed0425e7ae1fdcb456a28.json b/.sqlx/query-83992c141a7a1b6de48753c971d88915a117b585bcfed0425e7ae1fdcb456a28.json new file mode 100644 index 0000000..177411c --- /dev/null +++ b/.sqlx/query-83992c141a7a1b6de48753c971d88915a117b585bcfed0425e7ae1fdcb456a28.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n COALESCE(censored_tx_count, 0) AS censored_tx_count,\n COALESCE(censored_avg_delay, 0) AS censored_avg_delay,\n COALESCE(uncensored_tx_count, 0) AS uncensored_tx_count,\n COALESCE(uncensored_avg_delay, 0) AS uncensored_avg_delay\n FROM\n censorship_delay_30d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "censored_tx_count", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "censored_avg_delay", + "type_info": "Float8" + }, + { + "ordinal": 2, + "name": "uncensored_tx_count", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "uncensored_avg_delay", + "type_info": "Float8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null, + null, + null + ] + }, + "hash": "83992c141a7a1b6de48753c971d88915a117b585bcfed0425e7ae1fdcb456a28" +} diff --git a/.sqlx/query-8b70af619d8edd7797abcbf57e6105b60cd9f74fb87c4a68ce7e33b7a1eaf01c.json b/.sqlx/query-8b70af619d8edd7797abcbf57e6105b60cd9f74fb87c4a68ce7e33b7a1eaf01c.json new file mode 100644 index 0000000..37d28b6 --- /dev/null +++ b/.sqlx/query-8b70af619d8edd7797abcbf57e6105b60cd9f74fb87c4a68ce7e33b7a1eaf01c.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n operator_id,\n validator_count,\n relays\n FROM\n operators_all\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "operator_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "validator_count", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "relays", + "type_info": "TextArray" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + true, + true + ] + }, + "hash": "8b70af619d8edd7797abcbf57e6105b60cd9f74fb87c4a68ce7e33b7a1eaf01c" +} diff --git a/.sqlx/query-9c0d78883385fc3abb9112bb7aaa75badbada1b3374bfaa7fecb877e541bd089.json b/.sqlx/query-9c0d78883385fc3abb9112bb7aaa75badbada1b3374bfaa7fecb877e541bd089.json new file mode 100644 index 0000000..d8809f5 --- /dev/null +++ b/.sqlx/query-9c0d78883385fc3abb9112bb7aaa75badbada1b3374bfaa7fecb877e541bd089.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO missed_slots (slot_number, relayed_block_hash, canonical_block_hash)\n VALUES ($1, $2, $3)\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Varchar", + "Varchar" + ] + }, + "nullable": [] + }, + "hash": "9c0d78883385fc3abb9112bb7aaa75badbada1b3374bfaa7fecb877e541bd089" +} diff --git a/.sqlx/query-a875ca754e6eb830a0e407caf166dc9d5917fe2ea3600ede1781d891a2fef169.json b/.sqlx/query-a875ca754e6eb830a0e407caf166dc9d5917fe2ea3600ede1781d891a2fef169.json new file mode 100644 index 0000000..45e7d00 --- /dev/null +++ b/.sqlx/query-a875ca754e6eb830a0e407caf166dc9d5917fe2ea3600ede1781d891a2fef169.json @@ -0,0 +1,52 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n transactions_data.transaction_hash,\n transactions_data.block_number,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.blacklist,\n transactions_data.blocksdelay as block_delay\n FROM\n transactions_data\n WHERE\n (\n transactions_data.lowbasefee + transactions_data.lowtip + transactions_data.congested + transactions_data.low_balance\n )\n = 0\n AND transactions_data.blocksdelay > 0\n AND transactions_data.blacklist != '{NULL}'\n AND transactions_data.mined > (CURRENT_DATE - $1::interval)\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "transaction_hash", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "block_number", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "mined", + "type_info": "Timestamptz" + }, + { + "ordinal": 3, + "name": "delay", + "type_info": "Float8" + }, + { + "ordinal": 4, + "name": "blacklist", + "type_info": "TextArray" + }, + { + "ordinal": 5, + "name": "block_delay", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Interval" + ] + }, + "nullable": [ + false, + false, + false, + null, + false, + false + ] + }, + "hash": "a875ca754e6eb830a0e407caf166dc9d5917fe2ea3600ede1781d891a2fef169" +} diff --git a/.sqlx/query-a9e4c026ffc88f66c7710a25d796cd024d3f687645d6605b30e58b402ab2b5b4.json b/.sqlx/query-a9e4c026ffc88f66c7710a25d796cd024d3f687645d6605b30e58b402ab2b5b4.json new file mode 100644 index 0000000..7dcd5ea --- /dev/null +++ b/.sqlx/query-a9e4c026ffc88f66c7710a25d796cd024d3f687645d6605b30e58b402ab2b5b4.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT MAX(latest_header_slot)\n FROM header_delay_updates\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "max", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "a9e4c026ffc88f66c7710a25d796cd024d3f687645d6605b30e58b402ab2b5b4" +} diff --git a/.sqlx/query-b4b951edd34f5c90e9dfce62e1aa2872dc9effbfbab4c18ced24a2da2c79303f.json b/.sqlx/query-b4b951edd34f5c90e9dfce62e1aa2872dc9effbfbab4c18ced24a2da2c79303f.json new file mode 100644 index 0000000..c0d3a0f --- /dev/null +++ b/.sqlx/query-b4b951edd34f5c90e9dfce62e1aa2872dc9effbfbab4c18ced24a2da2c79303f.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n t_type AS delay_type,\n avg_delay::float,\n avg_block_delay::float,\n n AS tx_count\n FROM inclusion_delay_30d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "delay_type", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "avg_delay", + "type_info": "Float8" + }, + { + "ordinal": 2, + "name": "avg_block_delay", + "type_info": "Float8" + }, + { + "ordinal": 3, + "name": "tx_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + null, + null, + true + ] + }, + "hash": "b4b951edd34f5c90e9dfce62e1aa2872dc9effbfbab4c18ced24a2da2c79303f" +} diff --git a/.sqlx/query-b5cc8291238aa73eeecd4cff45538eac2a6b324ca30a3aa189fa448fe23060de.json b/.sqlx/query-b5cc8291238aa73eeecd4cff45538eac2a6b324ca30a3aa189fa448fe23060de.json new file mode 100644 index 0000000..812ef5d --- /dev/null +++ b/.sqlx/query-b5cc8291238aa73eeecd4cff45538eac2a6b324ca30a3aa189fa448fe23060de.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n t_type AS delay_type,\n avg_delay::float,\n avg_block_delay::float,\n n AS tx_count\n FROM inclusion_delay_7d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "delay_type", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "avg_delay", + "type_info": "Float8" + }, + { + "ordinal": 2, + "name": "avg_block_delay", + "type_info": "Float8" + }, + { + "ordinal": 3, + "name": "tx_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + null, + null, + true + ] + }, + "hash": "b5cc8291238aa73eeecd4cff45538eac2a6b324ca30a3aa189fa448fe23060de" +} diff --git a/.sqlx/query-c84abce611c428b46cb09a33a0cbc2fa83abddd5f5bf1f7c7d60650f45c1ff1b.json b/.sqlx/query-c84abce611c428b46cb09a33a0cbc2fa83abddd5f5bf1f7c7d60650f45c1ff1b.json new file mode 100644 index 0000000..c602896 --- /dev/null +++ b/.sqlx/query-c84abce611c428b46cb09a33a0cbc2fa83abddd5f5bf1f7c7d60650f45c1ff1b.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT COUNT(*) FROM missed_slots WHERE slot_number > $1 AND slot_number <= $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "c84abce611c428b46cb09a33a0cbc2fa83abddd5f5bf1f7c7d60650f45c1ff1b" +} diff --git a/.sqlx/query-d4b5b444c5ab41863031f44991fede1deba00ee9824a61d1f581f7a3faf4855a.json b/.sqlx/query-d4b5b444c5ab41863031f44991fede1deba00ee9824a61d1f581f7a3faf4855a.json new file mode 100644 index 0000000..2f73ab2 --- /dev/null +++ b/.sqlx/query-d4b5b444c5ab41863031f44991fede1deba00ee9824a61d1f581f7a3faf4855a.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT slot_number\n FROM missed_slots\n WHERE inserted_at > $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot_number", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Timestamptz" + ] + }, + "nullable": [ + false + ] + }, + "hash": "d4b5b444c5ab41863031f44991fede1deba00ee9824a61d1f581f7a3faf4855a" +} diff --git a/.sqlx/query-e30ab64d5f6a10b97794aa3d41d2e04b59971c5c0dcca12a5b50a82ed47caffa.json b/.sqlx/query-e30ab64d5f6a10b97794aa3d41d2e04b59971c5c0dcca12a5b50a82ed47caffa.json new file mode 100644 index 0000000..a2fb65c --- /dev/null +++ b/.sqlx/query-e30ab64d5f6a10b97794aa3d41d2e04b59971c5c0dcca12a5b50a82ed47caffa.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT MAX(slot)\n FROM auction_analysis\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "max", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "e30ab64d5f6a10b97794aa3d41d2e04b59971c5c0dcca12a5b50a82ed47caffa" +} diff --git a/.sqlx/query-e36963367ad97d3cca55b306281fc25569d33b705814c343f5883fbea25c9923.json b/.sqlx/query-e36963367ad97d3cca55b306281fc25569d33b705814c343f5883fbea25c9923.json new file mode 100644 index 0000000..0302a0a --- /dev/null +++ b/.sqlx/query-e36963367ad97d3cca55b306281fc25569d33b705814c343f5883fbea25c9923.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n bid as builder_id,\n COALESCE(censoring_pubkeys, 0) AS censoring_pubkeys,\n COALESCE(total_pubkeys, 0) AS total_pubkeys,\n COALESCE(number_of_blocks, 0) AS block_count\n FROM\n builders_30d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "builder_id", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "censoring_pubkeys", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "total_pubkeys", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "block_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + null, + null, + null + ] + }, + "hash": "e36963367ad97d3cca55b306281fc25569d33b705814c343f5883fbea25c9923" +} diff --git a/.sqlx/query-eec6d6ba6e6f4cdc1d98da19017a1f1fe30426c87e9c014bbf3cdf1f0bcd13db.json b/.sqlx/query-eec6d6ba6e6f4cdc1d98da19017a1f1fe30426c87e9c014bbf3cdf1f0bcd13db.json new file mode 100644 index 0000000..3401a2e --- /dev/null +++ b/.sqlx/query-eec6d6ba6e6f4cdc1d98da19017a1f1fe30426c87e9c014bbf3cdf1f0bcd13db.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT MAX(slot)\n FROM lookback_updates\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "max", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "eec6d6ba6e6f4cdc1d98da19017a1f1fe30426c87e9c014bbf3cdf1f0bcd13db" +} diff --git a/.sqlx/query-f6e651aecad08bfbee7c36cd19b65f0b970450c9527302e16549f0b6ac5f8b43.json b/.sqlx/query-f6e651aecad08bfbee7c36cd19b65f0b970450c9527302e16549f0b6ac5f8b43.json new file mode 100644 index 0000000..114b488 --- /dev/null +++ b/.sqlx/query-f6e651aecad08bfbee7c36cd19b65f0b970450c9527302e16549f0b6ac5f8b43.json @@ -0,0 +1,59 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n slot_number,\n block_number,\n block_hash,\n builder_pubkey,\n proposer_pubkey,\n relays,\n value::text\n FROM block_production\n WHERE\n slot_number >= $1\n AND slot_number <= $2\n ORDER BY slot_number ASC\n LIMIT 200\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot_number", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "block_number", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "block_hash", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "builder_pubkey", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "proposer_pubkey", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "relays", + "type_info": "TextArray" + }, + { + "ordinal": 6, + "name": "value", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + true, + true, + true, + null + ] + }, + "hash": "f6e651aecad08bfbee7c36cd19b65f0b970450c9527302e16549f0b6ac5f8b43" +} diff --git a/.sqlx/query-fe8f4a6223cc2347eb5a1275ad0d4bf5dc79c18b9551371627879f034169a4a8.json b/.sqlx/query-fe8f4a6223cc2347eb5a1275ad0d4bf5dc79c18b9551371627879f034169a4a8.json new file mode 100644 index 0000000..0d3cfe3 --- /dev/null +++ b/.sqlx/query-fe8f4a6223cc2347eb5a1275ad0d4bf5dc79c18b9551371627879f034169a4a8.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n builder_pubkey,\n builder_name,\n uncensored_blocks,\n total_blocks\n FROM\n builder_blocks_7d\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "builder_pubkey", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "builder_name", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "uncensored_blocks", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "total_blocks", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + true, + true, + true + ] + }, + "hash": "fe8f4a6223cc2347eb5a1275ad0d4bf5dc79c18b9551371627879f034169a4a8" +} diff --git a/Cargo.lock b/Cargo.lock index 7c8cb5c..166104c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,17 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.11" @@ -108,7 +97,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -119,14 +108,14 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] @@ -203,22 +192,30 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bigdecimal" -version = "0.3.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +checksum = "51d712318a27c7150326677b321a5fa91b55f6d9034ffd67f20319e147d40cee" dependencies = [ + "autocfg", + "libm", "num-bigint", "num-integer", "num-traits", @@ -235,6 +232,9 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -304,6 +304,21 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation" version = "0.9.4" @@ -378,6 +393,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -395,30 +421,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenvy" version = "0.15.7" @@ -466,7 +473,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -494,11 +501,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" -version = "2.5.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "fastrand" @@ -516,6 +539,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -590,13 +624,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -613,7 +647,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -707,46 +741,37 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.3.0", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash", "allocator-api2", ] [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown 0.14.5", + "hashbrown", ] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -778,6 +803,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "0.2.12" @@ -904,16 +938,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.3.0" @@ -921,7 +945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown", ] [[package]] @@ -930,15 +954,6 @@ version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "ipnet" version = "2.9.0" @@ -983,6 +998,9 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] [[package]] name = "libc" @@ -991,13 +1009,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "libredox" -version = "0.1.3" +name = "libm" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" dependencies = [ - "bitflags 2.6.0", - "libc", + "cc", + "pkg-config", + "vcpkg", ] [[package]] @@ -1133,6 +1158,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1148,6 +1190,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1155,6 +1208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1204,7 +1258,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1232,15 +1286,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "parking_lot" -version = "0.11.2" +name = "parking" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -1249,21 +1298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -1285,6 +1320,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1308,7 +1352,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1323,6 +1367,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.30" @@ -1412,15 +1477,6 @@ dependencies = [ "url", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1439,17 +1495,6 @@ dependencies = [ "bitflags 2.6.0", ] -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - [[package]] name = "regex" version = "1.10.6" @@ -1587,6 +1632,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1763,7 +1828,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1846,6 +1911,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "slab" version = "0.4.9" @@ -1860,6 +1935,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -1876,6 +1954,19 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] [[package]] name = "sqlformat" @@ -1889,72 +1980,77 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "27144619c6e5802f1380337a209d2ac1c431002dd74c6e60aebff3c506dc4f0c" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "a999083c1af5b5d6c071d34a708a19ba3e02106ad82ef7bbd69f5e48266b613b" dependencies = [ - "ahash 0.7.8", "atoi", - "base64 0.13.1", "bigdecimal", - "bitflags 1.3.2", "byteorder", "bytes", "chrono", "crc", "crossbeam-queue", - "dirs", - "dotenvy", "either", "event-listener", "futures-channel", "futures-core", "futures-intrusive", + "futures-io", "futures-util", + "hashbrown", "hashlink", "hex", - "hkdf", - "hmac", - "indexmap 1.9.3", - "itoa", - "libc", + "indexmap", "log", - "md-5", "memchr", - "num-bigint", + "native-tls", "once_cell", "paste", "percent-encoding", - "rand", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", + "tokio", "tokio-stream", + "tracing", "url", - "whoami", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23217eb7d86c584b8cbe0337b9eacf12ab76fe7673c513141ec42565698bb88" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776" dependencies = [ "dotenvy", "either", @@ -1967,21 +2063,122 @@ dependencies = [ "serde_json", "sha2", "sqlx-core", - "sqlx-rt", - "syn 1.0.109", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "5afe4c38a9b417b6a9a5eeffe7235d0a106716495536e7727d1c7f4b1ff3eba6" dependencies = [ - "native-tls", + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.6.0", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-native-tls", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1dbb157e65f10dbe01f729339c06d239120221c9ad9fa0ba8408c4cc18ecf21" +dependencies = [ + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.6.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2cdd83c008a622d94499c0006d8ee5f821f36c89b7d625c900e5dc30b5c5ee" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "tracing", + "url", ] [[package]] @@ -2001,17 +2198,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.72" @@ -2080,7 +2266,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -2151,7 +2337,7 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2167,7 +2353,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -2280,7 +2466,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -2343,7 +2529,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -2385,12 +2571,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - [[package]] name = "unicode_categories" version = "0.1.1" @@ -2474,7 +2654,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn", "wasm-bindgen-shared", ] @@ -2508,7 +2688,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2543,7 +2723,6 @@ checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ "redox_syscall 0.4.1", "wasite", - "web-sys", ] [[package]] @@ -2771,7 +2950,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0468dd8..c5bd3b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,12 +22,11 @@ redis = { version = "0.22.1", features = ["aio", "tokio-comp"] } reqwest = { version = "0.11", features = ["json", "gzip"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -sqlx = { version = "0.6.2", features = [ +sqlx = { version = "0.8.0", features = [ "chrono", "postgres", "runtime-tokio-native-tls", "bigdecimal", - "offline", ] } tokio = { version = "1", features = ["full"] } tokio-stream = "0.1.12" diff --git a/sqlx-data.json b/sqlx-data.json deleted file mode 100644 index d060aad..0000000 --- a/sqlx-data.json +++ /dev/null @@ -1,874 +0,0 @@ -{ - "db": "PostgreSQL", - "02a6ff6e2f997a5a57b5b35c416a45ce7917d4110a4a17bf24c637c7338ed9dd": { - "describe": { - "columns": [ - { - "name": "builder_pubkey", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "builder_name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "uncensored_blocks", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "total_blocks", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - true, - true, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n builder_pubkey,\n builder_name,\n uncensored_blocks,\n total_blocks\n FROM\n builder_blocks_30d\n " - }, - "02dc1734de68f766241196b5a33bc99cefb4379e1a9b4a099ea705b30e7bfbe0": { - "describe": { - "columns": [ - { - "name": "pubkey", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "builder_name", - "ordinal": 1, - "type_info": "Text" - } - ], - "nullable": [ - false, - true - ], - "parameters": { - "Left": [ - "TextArray" - ] - } - }, - "query": "\n SELECT\n pubkey,\n builder_name\n FROM\n builder_pubkeys\n WHERE\n pubkey = ANY($1)\n " - }, - "0cfa774a2cce1f084fa5cff3d3ee5631dbec2198bdb23b8eab7ab0d5f68e586f": { - "describe": { - "columns": [ - { - "name": "slot_number", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT slot_number\n FROM block_production\n ORDER BY slot_number ASC\n LIMIT 1\n " - }, - "1621984623036a1f8fc5be4f23153f975a134660297e4ec48c3f828d85ea4cfa": { - "describe": { - "columns": [ - { - "name": "transaction_hash", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "mined", - "ordinal": 1, - "type_info": "Timestamptz" - }, - { - "name": "delay", - "ordinal": 2, - "type_info": "Float8" - }, - { - "name": "block_number", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "block_delay", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "blacklist", - "ordinal": 5, - "type_info": "TextArray" - }, - { - "name": "reason", - "ordinal": 6, - "type_info": "Text" - } - ], - "nullable": [ - false, - false, - null, - false, - false, - null, - null - ], - "parameters": { - "Left": [ - "Interval" - ] - } - }, - "query": "SELECT\n *\nFROM\n (\n SELECT\n transactions_data.transaction_hash,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.block_number,\n transactions_data.blocksdelay as block_delay,\n CASE\n WHEN blacklist = '{NULL}' THEN '{}'::text[]\n ELSE blacklist\n END AS blacklist,\n CASE\n WHEN transactions_data.low_balance = 1 THEN 'likely_insufficient_balance'\n WHEN transactions_data.lowbasefee = 1 THEN 'lowbasefee'\n WHEN transactions_data.lowtip = 1 THEN 'lowtip'\n WHEN transactions_data.congested = 1 THEN 'congested'\n WHEN transactions_data.blacklist != '{NULL}' THEN 'ofac'\n ELSE 'unknown'\n END AS reason\n FROM\n transactions_data\n WHERE\n transactions_data.mined > (CURRENT_DATE - $1::interval)\n AND transactions_data.blocksdelay > 1\n ) sq\nWHERE\n reason = 'ofac'\n OR reason = 'unknown'\n" - }, - "18ea2228ecb0e48afe3ba2abdaa352bb8af24d3ebda29ffbae56fa5f97426479": { - "describe": { - "columns": [ - { - "name": "censored_tx_count", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "censored_avg_delay", - "ordinal": 1, - "type_info": "Float8" - }, - { - "name": "uncensored_tx_count", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "uncensored_avg_delay", - "ordinal": 3, - "type_info": "Float8" - } - ], - "nullable": [ - null, - null, - null, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n COALESCE(censored_tx_count, 0) AS censored_tx_count,\n COALESCE(censored_avg_delay, 0) AS censored_avg_delay,\n COALESCE(uncensored_tx_count, 0) AS uncensored_tx_count,\n COALESCE(uncensored_avg_delay, 0) AS uncensored_avg_delay\n FROM\n censorship_delay_7d\n " - }, - "2f1fb67525b8bf6dc46897f153f4784a247d5575336d37dab6c9ece41b6effc7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Varchar", - "Varchar", - "Varchar", - "TextArray", - "Numeric" - ] - } - }, - "query": "\n INSERT INTO block_production (slot_number, block_number, block_hash, builder_pubkey, proposer_pubkey, relays, value)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (slot_number, block_number, block_hash)\n DO UPDATE SET\n relays = ARRAY (SELECT DISTINCT UNNEST(block_production.relays || $6)),\n value = $7\n " - }, - "3b46131f6339a8f8f12f3bfc6e4e2a511f86c45a2ec6b38495cb3cb046b616e1": { - "describe": { - "columns": [ - { - "name": "timestamp", - "ordinal": 0, - "type_info": "Timestamptz" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT timestamp\n FROM monitor_checkpoints\n WHERE monitor_id = $1\n LIMIT 1\n " - }, - "42a5b7e42b58c30dd938249b7deed8ce306ab50c376ddc94a50c221249785709": { - "describe": { - "columns": [ - { - "name": "relay_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "total_blocks", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "uncensored_blocks", - "ordinal": 2, - "type_info": "Int8" - } - ], - "nullable": [ - true, - true, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n relay_id,\n total_blocks,\n uncensored_blocks\n FROM\n relay_censorship_7d\n " - }, - "4edb1b52690629a38cb7d5030f4fd98267a2af5496e2a03ac63535a715f8e7b0": { - "describe": { - "columns": [ - { - "name": "transaction_hash", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "mined", - "ordinal": 1, - "type_info": "Timestamptz" - }, - { - "name": "delay", - "ordinal": 2, - "type_info": "Float8" - }, - { - "name": "block_number", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "block_delay", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "blacklist", - "ordinal": 5, - "type_info": "TextArray" - }, - { - "name": "reason", - "ordinal": 6, - "type_info": "Text" - } - ], - "nullable": [ - false, - false, - null, - false, - false, - null, - null - ], - "parameters": { - "Left": [ - "Interval", - "Int8" - ] - } - }, - "query": "SELECT\n transactions_data.transaction_hash,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.block_number,\n transactions_data.blocksdelay as block_delay,\n CASE\n WHEN blacklist = '{NULL}' THEN '{}'::text[]\n ELSE blacklist\n END AS blacklist,\n CASE\n WHEN transactions_data.low_balance = 1 THEN 'likely_insufficient_balance'\n WHEN transactions_data.lowbasefee = 1 THEN 'lowbasefee'\n WHEN transactions_data.lowtip = 1 THEN 'lowtip'\n WHEN transactions_data.congested = 1 THEN 'congested'\n WHEN transactions_data.blacklist != '{NULL}' THEN 'ofac'\n ELSE 'unknown'\n END AS reason\n FROM\n transactions_data\n WHERE\n transactions_data.mined > (CURRENT_DATE - $1::interval)\n AND transactions_data.blocksdelay > 1\n ORDER BY\n transactions_data.mined DESC\n LIMIT $2\n" - }, - "4fe072ed2dc31c6239efa122c1f9087e50d4e76499f52d4f79befe04fd80317e": { - "describe": { - "columns": [ - { - "name": "builder_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "censoring_pubkeys", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "total_pubkeys", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "block_count", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - null, - null, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n bid as builder_id,\n COALESCE(censoring_pubkeys, 0) AS censoring_pubkeys,\n COALESCE(total_pubkeys, 0) AS total_pubkeys,\n COALESCE(number_of_blocks, 0) AS block_count\n FROM\n builders_7d\n " - }, - "567c4f271b33e91b4fd31cca7057c03aed3fc1c1b91b21090e4d17f1c2cc6b56": { - "describe": { - "columns": [ - { - "name": "timestamp", - "ordinal": 0, - "type_info": "Timestamptz" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "SELECT timestamp FROM blocks ORDER BY timestamp DESC LIMIT 1" - }, - "57e76c5f66376b4f6afed09b85f259ff0111a950e9da769b5804f91129246705": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Timestamptz" - ] - } - }, - "query": "\n INSERT INTO monitor_checkpoints (monitor_id, timestamp)\n VALUES ($1, $2)\n ON CONFLICT (monitor_id) DO UPDATE SET timestamp = $2\n " - }, - "60c76c079e46f42a1cfbe737ea246d56d1bb3984470677da3cbe3260e2a29d7c": { - "describe": { - "columns": [ - { - "name": "relay_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "block_count", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "total_value", - "ordinal": 2, - "type_info": "Float8" - }, - { - "name": "avg_value", - "ordinal": 3, - "type_info": "Float8" - } - ], - "nullable": [ - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Interval" - ] - } - }, - "query": "\n SELECT\n UNNEST(relays) AS relay_id,\n COUNT(*) AS block_count,\n SUM(value / array_length(relays, 1)) / 10^18 AS total_value,\n AVG(value / array_length(relays, 1)) / 10^18 AS avg_value\n FROM\n block_production\n WHERE\n inserted_at >= NOW() - $1::interval\n GROUP BY\n relay_id\n " - }, - "6f2ba37d7de520fbbbea680170556ffee644e58264a09f768c5feba34f8a7577": { - "describe": { - "columns": [ - { - "name": "relay_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "total_blocks", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "uncensored_blocks", - "ordinal": 2, - "type_info": "Int8" - } - ], - "nullable": [ - true, - true, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n relay_id,\n total_blocks,\n uncensored_blocks\n FROM\n relay_censorship_30d\n\n " - }, - "83992c141a7a1b6de48753c971d88915a117b585bcfed0425e7ae1fdcb456a28": { - "describe": { - "columns": [ - { - "name": "censored_tx_count", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "censored_avg_delay", - "ordinal": 1, - "type_info": "Float8" - }, - { - "name": "uncensored_tx_count", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "uncensored_avg_delay", - "ordinal": 3, - "type_info": "Float8" - } - ], - "nullable": [ - null, - null, - null, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n COALESCE(censored_tx_count, 0) AS censored_tx_count,\n COALESCE(censored_avg_delay, 0) AS censored_avg_delay,\n COALESCE(uncensored_tx_count, 0) AS uncensored_tx_count,\n COALESCE(uncensored_avg_delay, 0) AS uncensored_avg_delay\n FROM\n censorship_delay_30d\n " - }, - "8b70af619d8edd7797abcbf57e6105b60cd9f74fb87c4a68ce7e33b7a1eaf01c": { - "describe": { - "columns": [ - { - "name": "operator_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "validator_count", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "relays", - "ordinal": 2, - "type_info": "TextArray" - } - ], - "nullable": [ - true, - true, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n operator_id,\n validator_count,\n relays\n FROM\n operators_all\n " - }, - "9c0d78883385fc3abb9112bb7aaa75badbada1b3374bfaa7fecb877e541bd089": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO missed_slots (slot_number, relayed_block_hash, canonical_block_hash)\n VALUES ($1, $2, $3)\n " - }, - "a81f8d6a22e778ca9006989860792c87ed3851d22dfb2438e4a7169331d6fab8": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Text" - ] - } - }, - "query": "\n UPDATE transactions_data\n SET low_balance = $1\n WHERE transaction_hash = $2\n " - }, - "a875ca754e6eb830a0e407caf166dc9d5917fe2ea3600ede1781d891a2fef169": { - "describe": { - "columns": [ - { - "name": "transaction_hash", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "block_number", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "mined", - "ordinal": 2, - "type_info": "Timestamptz" - }, - { - "name": "delay", - "ordinal": 3, - "type_info": "Float8" - }, - { - "name": "blacklist", - "ordinal": 4, - "type_info": "TextArray" - }, - { - "name": "block_delay", - "ordinal": 5, - "type_info": "Int4" - } - ], - "nullable": [ - false, - false, - false, - null, - false, - false - ], - "parameters": { - "Left": [ - "Interval" - ] - } - }, - "query": "SELECT\n transactions_data.transaction_hash,\n transactions_data.block_number,\n transactions_data.mined,\n transactions_data.delay::float,\n transactions_data.blacklist,\n transactions_data.blocksdelay as block_delay\n FROM\n transactions_data\n WHERE\n (\n transactions_data.lowbasefee + transactions_data.lowtip + transactions_data.congested + transactions_data.low_balance\n )\n = 0\n AND transactions_data.blocksdelay > 0\n AND transactions_data.blacklist != '{NULL}'\n AND transactions_data.mined > (CURRENT_DATE - $1::interval)\n" - }, - "afea0d23aaf492036a9bee18e9655317920f36146ae3f66e7d4855992a57e698": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [] - } - }, - "query": "WITH inserted_rows as (\nINSERT INTO\n transactions_data\n SELECT\n \"NEST2\".transaction_hash,\n min(\"NEST2\".tbn) AS blocknumber,\n min(\"NEST2\".minertx) AS minertransaction,\n max(\"NEST2\".lowbasefee) AS lowbasefee,\n max(\"NEST2\".congestion) AS congested,\n CASE\n WHEN\n count(DISTINCT \"NEST2\".block_number) > 0\n AND max(\"NEST2\".lowbasefee) < 1\n THEN\n max(\"NEST2\".lowfeetip)\n ELSE\n 0\n END\n AS lowtip, min(\"NEST2\".blockts) AS mined, max(\"NEST2\".delay) AS delay, array_agg(DISTINCT \"NEST2\".blacklist) AS blacklist, count(DISTINCT \"NEST2\".block_number) AS blocksdelay\n FROM\n (\n SELECT\n \"NEST\".minertx,\n \"NEST\".tbn,\n \"NEST\".blockts,\n \"NEST\".prevts,\n \"NEST\".transaction_hash,\n blocks.block_number,\n CASE\n WHEN\n \"NEST\".bf < blocks.base_fee_per_gas\n THEN\n 1\n ELSE\n 0\n END\n AS lowbasefee,\n CASE\n WHEN\n (\n \"NEST\".bf - blocks.base_fee_per_gas\n )\n >= 1000000000 AND \"NEST\".pf>=1000000000 and tt=2\n THEN\n 0\n WHEN\n (\n \"NEST\".bf - blocks.base_fee_per_gas\n )\n >= 1000000000 AND tt=0\n THEN 0\n ELSE\n 1\n END\n AS lowfeetip, blocks.gas_limit AS gaslimit, blocks.gas_used AS gasused, \"NEST\".gas,\n CASE\n WHEN\n \"NEST\".gas > (blocks.gas_limit - blocks.gas_used)\n THEN\n 1\n ELSE\n 0\n END\n AS congestion, \"NEST\".delay, \"NEST\".blacklist,\n 9 as low_balance\n FROM\n (\n SELECT\n transactions.transaction_hash,\n min(transactions.block_number) AS tbn,\n CASE\n WHEN\n min(transactions.max_fee_per_gas) IS NOT NULL\n THEN\n min(transactions.max_fee_per_gas)\n ELSE\n min(transactions.gas_price)\n END\n AS bf,\n min(transactions.max_priority_fee_per_gas) as pf,\n min (transactions.transaction_type) as tt,\n min(transactions.gas) AS gas, min(blocks_1.\"timestamp\") AS blockts, min(mempool_timestamps.\"timestamp\") AS memts,\n CASE\n WHEN\n (\n min(extract(epoch\n FROM\n blocks_1.\"timestamp\")) - ((\n SELECT\n percentile_cont(0.5) WITHIN GROUP (\n ORDER BY\n(mempool_timestamps.timestamp_unix)) AS percentile_cont))\n )\n <= 0\n THEN\n 0\n ELSE\n min(extract(epoch\n FROM\n blocks_1.\"timestamp\")) - greatest(extract(epoch\n FROM\n min(transactions.prev_nonce_timestamp)),\n (\n(\n SELECT\n percentile_cont(0.5) WITHIN GROUP (\n ORDER BY\n(mempool_timestamps.timestamp_unix)) AS percentile_cont)\n )\n)\n END\n AS delay,\n CASE\n WHEN\n (\n min(extract(epoch\n FROM\n blocks_1.\"timestamp\")) - ((\n SELECT\n percentile_cont(0.5) WITHIN GROUP (\n ORDER BY\n(mempool_timestamps.timestamp_unix)) AS percentile_cont))\n )\n <= 0\n THEN\n 1\n ELSE\n 0\n END\n AS minertx, min(blocks_1.block_number) AS bn, max(transaction_blacklists.blacklist_id) AS blacklist, min(transactions.prev_nonce_timestamp) AS prevts\n FROM\n transactions\n LEFT JOIN\n blocks blocks_1\n ON blocks_1.block_number = transactions.block_number\n LEFT JOIN\n (\n SELECT\n \"NEST2_1\".transaction_hash,\n min(\"NEST2_1\".blacklist_id) AS blacklist_id\n FROM\n (\n SELECT\n \"NEST_1\".transaction_hash,\n \"NEST_1\".trace,\n blacklist_entries.display_name,\n blacklist_entries.blacklist_id\n FROM\n (\n SELECT\n transactions_1.transaction_hash,\n unnest(transactions_1.address_trace) AS trace,\n transactions_1.block_timestamp\n FROM\n transactions transactions_1\n )\n \"NEST_1\"\n LEFT JOIN\n blacklist_entries\n ON blacklist_entries.address = \"NEST_1\".trace\n WHERE\n (\n \"NEST_1\".trace IN\n (\n SELECT\n blacklist_entries_1.address\n FROM\n blacklist_entries blacklist_entries_1\n )\n )\n AND \"NEST_1\".block_timestamp > blacklist_entries.date_added\n )\n \"NEST2_1\"\n GROUP BY\n \"NEST2_1\".transaction_hash\n )\n transaction_blacklists\n ON transaction_blacklists.transaction_hash = transactions.transaction_hash\n INNER JOIN\n mempool_timestamps\n ON mempool_timestamps.transaction_hash = transactions.transaction_hash\n WHERE\n transactions.block_timestamp > (\n SELECT\n GREATEST('2020-01-01', MAX(transactions_data.mined))\n from\n transactions_data)\n GROUP BY\n transactions.transaction_hash,\n blocks_1.gas_limit,\n blocks_1.gas_used\n )\n \"NEST\"\n LEFT JOIN\n blocks\n ON blocks.\"timestamp\" > GREATEST (\"NEST\".memts, \"NEST\".prevts)\n AND blocks.\"timestamp\" < \"NEST\".blockts\n )\n \"NEST2\"\n GROUP BY\n \"NEST2\".transaction_hash\n ON CONFLICT (transaction_hash) DO NOTHING\n RETURNING 1\n)\n\nSELECT COUNT(*) FROM inserted_rows;\n" - }, - "b4b951edd34f5c90e9dfce62e1aa2872dc9effbfbab4c18ced24a2da2c79303f": { - "describe": { - "columns": [ - { - "name": "delay_type", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "avg_delay", - "ordinal": 1, - "type_info": "Float8" - }, - { - "name": "avg_block_delay", - "ordinal": 2, - "type_info": "Float8" - }, - { - "name": "tx_count", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - null, - null, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n t_type AS delay_type,\n avg_delay::float,\n avg_block_delay::float,\n n AS tx_count\n FROM inclusion_delay_30d\n " - }, - "b5cc8291238aa73eeecd4cff45538eac2a6b324ca30a3aa189fa448fe23060de": { - "describe": { - "columns": [ - { - "name": "delay_type", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "avg_delay", - "ordinal": 1, - "type_info": "Float8" - }, - { - "name": "avg_block_delay", - "ordinal": 2, - "type_info": "Float8" - }, - { - "name": "tx_count", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - null, - null, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n t_type AS delay_type,\n avg_delay::float,\n avg_block_delay::float,\n n AS tx_count\n FROM inclusion_delay_7d\n " - }, - "c84abce611c428b46cb09a33a0cbc2fa83abddd5f5bf1f7c7d60650f45c1ff1b": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT COUNT(*) FROM missed_slots WHERE slot_number > $1 AND slot_number <= $2" - }, - "d4b5b444c5ab41863031f44991fede1deba00ee9824a61d1f581f7a3faf4855a": { - "describe": { - "columns": [ - { - "name": "slot_number", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Timestamptz" - ] - } - }, - "query": "\n SELECT slot_number\n FROM missed_slots\n WHERE inserted_at > $1\n " - }, - "df8ad42619e4bd31754b0f76e37a0bb2a01e3b0002549c3cd6c19bd5086e2e33": { - "describe": { - "columns": [ - { - "name": "transaction_hash", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "from_address", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "total_value", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "block_number", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - null, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n tx.transaction_hash,\n tx.from_address,\n (tx.value + tx.receipt_effective_gas_price * tx.receipt_gas_used)::text AS total_value,\n tx.block_number - txd.blocksdelay AS block_number\n FROM\n transactions_data txd\n INNER JOIN\n transactions tx\n ON tx.transaction_hash = txd.transaction_hash\n WHERE\n txd.blocksdelay > 2\n AND minertransaction + lowbasefee + congested + lowtip = 0\n AND low_balance = 9\n " - }, - "e36963367ad97d3cca55b306281fc25569d33b705814c343f5883fbea25c9923": { - "describe": { - "columns": [ - { - "name": "builder_id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "censoring_pubkeys", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "total_pubkeys", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "block_count", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - null, - null, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n bid as builder_id,\n COALESCE(censoring_pubkeys, 0) AS censoring_pubkeys,\n COALESCE(total_pubkeys, 0) AS total_pubkeys,\n COALESCE(number_of_blocks, 0) AS block_count\n FROM\n builders_30d\n " - }, - "f6e651aecad08bfbee7c36cd19b65f0b970450c9527302e16549f0b6ac5f8b43": { - "describe": { - "columns": [ - { - "name": "slot_number", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "block_number", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "block_hash", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "builder_pubkey", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "proposer_pubkey", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "relays", - "ordinal": 5, - "type_info": "TextArray" - }, - { - "name": "value", - "ordinal": 6, - "type_info": "Text" - } - ], - "nullable": [ - false, - false, - false, - true, - true, - true, - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT\n slot_number,\n block_number,\n block_hash,\n builder_pubkey,\n proposer_pubkey,\n relays,\n value::text\n FROM block_production\n WHERE\n slot_number >= $1\n AND slot_number <= $2\n ORDER BY slot_number ASC\n LIMIT 200\n " - }, - "fe8f4a6223cc2347eb5a1275ad0d4bf5dc79c18b9551371627879f034169a4a8": { - "describe": { - "columns": [ - { - "name": "builder_pubkey", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "builder_name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "uncensored_blocks", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "total_blocks", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - true, - true, - true, - true - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT\n builder_pubkey,\n builder_name,\n uncensored_blocks,\n total_blocks\n FROM\n builder_blocks_7d\n " - } -} \ No newline at end of file diff --git a/src/phoenix/auction_analysis_monitor.rs b/src/phoenix/auction_analysis_monitor.rs new file mode 100644 index 0000000..3a7b43d --- /dev/null +++ b/src/phoenix/auction_analysis_monitor.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use sqlx::PgPool; +use tracing::debug; + +use super::util::get_current_slot; + +use crate::phoenix::{Alarm, AlarmType}; + +use super::env::APP_CONFIG; + +async fn get_latest_auction_analysis_slot(mev_pool: &PgPool) -> anyhow::Result { + sqlx::query_scalar!( + r#" + SELECT MAX(slot) + FROM auction_analysis + "#, + ) + .fetch_one(mev_pool) + .await + .map(|max| { + max.expect("No maximum slot found from auction_analysis") + .try_into() + .expect("Maximum slot is negative") + }) + .map_err(Into::into) +} + +pub async fn run_auction_analysis_monitor(mev_pool: &PgPool, alarm: &mut Alarm) -> Result<()> { + let latest_slot = get_latest_auction_analysis_slot(mev_pool).await?; + let current_slot = get_current_slot()?; + let slot_lag = current_slot - latest_slot; + debug!( + "Auction analysis is {:} slots behind current slot", + slot_lag + ); + if slot_lag > APP_CONFIG.max_auction_analysis_slot_lag { + let message = format!( + "Auction analysis is {:} slots behind the current slot", + slot_lag + ); + alarm.fire(&message, &AlarmType::Telegram).await; + } + Ok(()) +} diff --git a/src/phoenix/delay_update_monitor.rs b/src/phoenix/delay_update_monitor.rs new file mode 100644 index 0000000..af44720 --- /dev/null +++ b/src/phoenix/delay_update_monitor.rs @@ -0,0 +1,43 @@ +use anyhow::Result; +use sqlx::PgPool; +use tracing::debug; + +use super::util::get_current_slot; +use crate::phoenix::{Alarm, AlarmType}; + +use super::env::APP_CONFIG; + +async fn get_latest_header_delay_updates_slot(mev_pool: &PgPool) -> anyhow::Result { + sqlx::query_scalar!( + r#" + SELECT MAX(latest_header_slot) + FROM header_delay_updates + "#, + ) + .fetch_one(mev_pool) + .await + .map(|max| { + max.expect("No maximum slot found from header_delay_updates") + .try_into() + .expect("Maximum slot is negative") + }) + .map_err(Into::into) +} + +pub async fn run_header_delay_updates_monitor(mev_pool: &PgPool, alarm: &mut Alarm) -> Result<()> { + let latest_slot = get_latest_header_delay_updates_slot(mev_pool).await?; + let current_slot = get_current_slot()?; + let slot_lag = current_slot - latest_slot; + debug!( + "header_delay_updates is {:} slots behind current slot", + slot_lag + ); + if slot_lag > APP_CONFIG.max_header_delay_updates_slot_lag { + let message = format!( + "header_delay_updates is {:} slots behind the current slot", + slot_lag + ); + alarm.fire(&message, &AlarmType::Telegram).await; + } + Ok(()) +} diff --git a/src/phoenix/env.rs b/src/phoenix/env.rs index 79d21c3..c94c9eb 100644 --- a/src/phoenix/env.rs +++ b/src/phoenix/env.rs @@ -33,6 +33,27 @@ pub struct AppConfig { pub unsynced_nodes_threshold_tg_warning: usize, #[serde(default = "default_unsynced_nodes_threshold_og_alert")] pub unsynced_nodes_threshold_og_alert: usize, + #[serde(default = "default_max_auction_analysis_slot_lag")] + pub max_auction_analysis_slot_lag: u32, + #[serde(default = "default_max_header_delay_updates_slot_lag")] + pub max_header_delay_updates_slot_lag: u32, + #[serde(default = "default_max_lookback_updates_slot_lag")] + pub max_lookback_updates_slot_lag: u32, +} + +fn default_max_lookback_updates_slot_lag() -> u32 { + // Note that this is more heuristic: since theoretically there could just be no updates because + // of the way the update algorithm works + 600 +} + +fn default_max_header_delay_updates_slot_lag() -> u32 { + // Should be configured considering the configured schedule for the update cron job + 60 +} + +fn default_max_auction_analysis_slot_lag() -> u32 { + 50 } fn default_unsynced_nodes_threshold_og_alert() -> usize { diff --git a/src/phoenix/lookback_update_monitor.rs b/src/phoenix/lookback_update_monitor.rs new file mode 100644 index 0000000..0d87f82 --- /dev/null +++ b/src/phoenix/lookback_update_monitor.rs @@ -0,0 +1,43 @@ +use anyhow::Result; +use sqlx::PgPool; +use tracing::debug; + +use super::util::get_current_slot; +use crate::phoenix::{Alarm, AlarmType}; + +use super::env::APP_CONFIG; + +async fn get_latest_lookback_updates_slot(mev_pool: &PgPool) -> anyhow::Result { + sqlx::query_scalar!( + r#" + SELECT MAX(slot) + FROM lookback_updates + "#, + ) + .fetch_one(mev_pool) + .await + .map(|max| { + max.expect("No maximum slot found from lookback_updates") + .try_into() + .expect("Maximum slot is negative") + }) + .map_err(Into::into) +} + +pub async fn run_lookback_updates_monitor(mev_pool: &PgPool, alarm: &mut Alarm) -> Result<()> { + let latest_slot = get_latest_lookback_updates_slot(mev_pool).await?; + let current_slot = get_current_slot()?; + let slot_lag = current_slot - latest_slot; + debug!( + "lookback_updates is {:} slots behind current slot", + slot_lag + ); + if slot_lag > APP_CONFIG.max_lookback_updates_slot_lag { + let message = format!( + "lookback_updates is {:} slots behind the current slot", + slot_lag + ); + alarm.fire(&message, &AlarmType::Telegram).await; + } + Ok(()) +} diff --git a/src/phoenix/mod.rs b/src/phoenix/mod.rs index 2af14de..247336f 100644 --- a/src/phoenix/mod.rs +++ b/src/phoenix/mod.rs @@ -1,13 +1,18 @@ mod alerts; +mod auction_analysis_monitor; mod checkpoint; mod consensus_node; +mod delay_update_monitor; mod demotion_monitor; mod env; mod inclusion_monitor; +mod lookback_update_monitor; mod promotion_monitor; +mod util; mod validation_node; use std::{ + collections::HashMap, net::SocketAddr, sync::{Arc, Mutex}, }; @@ -33,8 +38,11 @@ use self::{ telegram::{self, TelegramAlerts, TelegramSafeAlert}, SendAlert, }, + auction_analysis_monitor::run_auction_analysis_monitor, + delay_update_monitor::run_header_delay_updates_monitor, demotion_monitor::run_demotion_monitor, inclusion_monitor::{run_inclusion_monitor, LokiClient}, + lookback_update_monitor::run_lookback_updates_monitor, promotion_monitor::run_promotion_monitor, }; @@ -44,31 +52,37 @@ lazy_static! { static ref MIN_WARNING_WAIT: Duration = Duration::minutes(60); } -struct Alarm { - last_fired: Option>, - telegram_alerts: TelegramAlerts, -} - +#[derive(Clone, Eq, Hash, PartialEq)] enum AlarmType { Telegram, Opsgenie, } +impl AlarmType { + fn min_wait(&self) -> Duration { + match self { + AlarmType::Opsgenie => *MIN_ALARM_WAIT, + AlarmType::Telegram => *MIN_WARNING_WAIT, + } + } +} + +struct Alarm { + last_fired: HashMap>, + telegram_alerts: TelegramAlerts, +} + impl Alarm { fn new() -> Self { Self { - last_fired: None, + last_fired: HashMap::new(), telegram_alerts: TelegramAlerts::new(), } } fn is_throttled(&self, alarm_type: &AlarmType) -> bool { - self.last_fired.map_or(false, |last_fired| { - let min_wait = match alarm_type { - AlarmType::Opsgenie => *MIN_ALARM_WAIT, - AlarmType::Telegram => *MIN_WARNING_WAIT, - }; - Utc::now() - last_fired < min_wait + self.last_fired.get(alarm_type).map_or(false, |last_fired| { + Utc::now() - last_fired < alarm_type.min_wait() }) } @@ -89,7 +103,19 @@ impl Alarm { } } - self.last_fired = Some(Utc::now()); + self.last_fired.insert(alarm_type.clone(), Utc::now()); + } +} + +struct NodeAlarm { + alarm: Alarm, +} + +impl NodeAlarm { + fn new() -> Self { + Self { + alarm: Alarm::new(), + } } async fn fire_age_over_limit(&mut self, name: &str) { @@ -98,17 +124,17 @@ impl Alarm { name, PHOENIX_MAX_LIFESPAN.num_seconds(), ); - self.fire(&message, &AlarmType::Opsgenie).await; + self.alarm.fire(&message, &AlarmType::Opsgenie).await; } async fn fire_num_unsynced_nodes(&mut self, name: &str, num_unsynced_nodes: usize) { let message = format!("{} has {} unsynced instances", name, num_unsynced_nodes); if num_unsynced_nodes >= APP_CONFIG.unsynced_nodes_threshold_og_alert { - self.fire(&message, &AlarmType::Opsgenie).await; + self.alarm.fire(&message, &AlarmType::Opsgenie).await; } if num_unsynced_nodes >= APP_CONFIG.unsynced_nodes_threshold_tg_warning { - self.fire(&message, &AlarmType::Telegram).await; + self.alarm.fire(&message, &AlarmType::Telegram).await; } } } @@ -150,7 +176,7 @@ async fn run_alarm_loop(last_checked: Arc>>) -> Result<()> { PHOENIX_MAX_LIFESPAN.num_seconds() ); - let mut alarm = Alarm::new(); + let mut alarm = NodeAlarm::new(); let mut phoenixes = [ Phoenix { @@ -257,11 +283,19 @@ async fn run_ops_monitors() -> Result<()> { .await?; let loki_client = LokiClient::new(APP_CONFIG.loki_url.clone()); + // Separate alarm instances mean throtteling will be applied separately + let mut auction_analysis_alarm = Alarm::new(); + let mut header_delay_updates_alarm = Alarm::new(); + let mut run_lookback_updates_monitor_alarm = Alarm::new(); + loop { let canonical_horizon = Utc::now() - Duration::minutes(APP_CONFIG.canonical_wait_minutes); run_demotion_monitor(&relay_pool, &mev_pool).await?; run_inclusion_monitor(&relay_pool, &mev_pool, &canonical_horizon, &loki_client).await?; run_promotion_monitor(&relay_pool, &mev_pool, &canonical_horizon).await?; + run_auction_analysis_monitor(&mev_pool, &mut auction_analysis_alarm).await?; + run_header_delay_updates_monitor(&mev_pool, &mut header_delay_updates_alarm).await?; + run_lookback_updates_monitor(&mev_pool, &mut run_lookback_updates_monitor_alarm).await?; tokio::time::sleep(Duration::minutes(1).to_std().unwrap()).await; } } diff --git a/src/phoenix/util.rs b/src/phoenix/util.rs new file mode 100644 index 0000000..6f56517 --- /dev/null +++ b/src/phoenix/util.rs @@ -0,0 +1,22 @@ +use super::env::APP_CONFIG; +use crate::env::{Network, ToNetwork}; +use anyhow::Result; +use chrono::{DateTime, Utc}; +use lazy_static::lazy_static; + +lazy_static! { + static ref GENESIS_TIMESTAMP: DateTime = { + match &APP_CONFIG.env.to_network() { + Network::Mainnet => "2020-12-01T12:00:23Z".parse().unwrap(), + Network::Holesky => "2023-09-28T12:00:00Z".parse().unwrap(), + } + }; +} + +const SECONDS_PER_SLOT: u8 = 12; + +pub fn get_current_slot() -> Result { + let now = Utc::now(); + let seconds_since_genesis: u32 = (now - *GENESIS_TIMESTAMP).num_seconds().try_into()?; + Ok(seconds_since_genesis / SECONDS_PER_SLOT as u32) +}