From b1cb8afb40b7fa2ddbe9bbde82732ad78c60692b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lasse=20M=C3=B8ldrup?= Date: Wed, 11 Oct 2023 09:50:40 +0200 Subject: [PATCH] Add active bakers graphs --- kpi-tracker/Cargo.lock | 155 ++++++++++++++++------------- kpi-tracker/grafana/dashboard.json | 154 ++++++++++++++++++++++++++-- kpi-tracker/resources/schema.sql | 10 +- kpi-tracker/src/main.rs | 101 +++++++++++-------- 4 files changed, 300 insertions(+), 120 deletions(-) diff --git a/kpi-tracker/Cargo.lock b/kpi-tracker/Cargo.lock index 4c06781f..8a143f71 100644 --- a/kpi-tracker/Cargo.lock +++ b/kpi-tracker/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -177,7 +177,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -188,7 +188,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -500,7 +500,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -541,7 +541,7 @@ version = "4.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -674,7 +674,7 @@ version = "1.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -795,7 +795,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -806,7 +806,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -916,25 +916,14 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -1040,7 +1029,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1397,15 +1386,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "linux-raw-sys" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" @@ -1441,9 +1430,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -1576,9 +1565,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -1611,7 +1600,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1740,7 +1729,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1823,9 +1812,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -2009,9 +1998,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.6" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" dependencies = [ "aho-corasick", "memchr", @@ -2021,9 +2010,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", @@ -2032,9 +2021,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" [[package]] name = "rend" @@ -2054,12 +2043,26 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "rkyv" version = "0.7.42" @@ -2121,9 +2124,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.15" +version = "0.38.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" +checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" dependencies = [ "bitflags 2.4.0", "errno", @@ -2139,7 +2142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] @@ -2198,8 +2201,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -2251,9 +2254,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" @@ -2272,7 +2275,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2312,7 +2315,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2417,6 +2420,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stringprep" version = "0.1.4" @@ -2453,9 +2462,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -2500,7 +2509,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2548,9 +2557,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -2582,7 +2591,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2760,7 +2769,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2831,6 +2840,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "utf8parse" version = "0.2.1" @@ -2891,7 +2906,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -2913,7 +2928,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2936,12 +2951,12 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.2" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.3", + "untrusted 0.9.0", ] [[package]] @@ -3062,9 +3077,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" dependencies = [ "memchr", ] @@ -3095,5 +3110,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] diff --git a/kpi-tracker/grafana/dashboard.json b/kpi-tracker/grafana/dashboard.json index 77e4e992..e67a4646 100644 --- a/kpi-tracker/grafana/dashboard.json +++ b/kpi-tracker/grafana/dashboard.json @@ -64,7 +64,7 @@ "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", + "lineInterpolation": "stepAfter", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { @@ -127,7 +127,7 @@ "editorMode": "code", "format": "time_series", "rawQuery": true, - "rawSql": "SELECT\n $__unixEpochGroup(timestamp, $__interval) AS time,\n SUM(total_stake::DECIMAL/1000000) as stake_ccd\nFROM blocks\nWHERE total_stake IS NOT NULL\nAND $__unixEpochFilter(timestamp)\nGROUP BY $__unixEpochGroup(timestamp, $__interval);", + "rawSql": "SELECT\n $__unixEpochGroup(timestamp, $__interval) AS time,\n paydays.total_stake::DECIMAL/1000000 as stake_ccd\nFROM blocks\nJOIN paydays ON paydays.block = blocks.id;", "refId": "A", "sql": { "columns": [ @@ -827,7 +827,7 @@ "overrides": [] }, "gridPos": { - "h": 10, + "h": 8, "w": 12, "x": 12, "y": 30 @@ -878,13 +878,149 @@ "title": "Smart contracts (modules)", "type": "timeseries" }, + { + "datasource": { + "type": "postgres", + "uid": "${postgres_db}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "stepAfter", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "active_bakers" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 31, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${postgres_db}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT\n paydays.num_bakers as active_bakers,\n $__unixEpochGroup(timestamp, $__interval) AS time\nFROM paydays\nJOIN blocks ON blocks.id = paydays.block;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Active Bakers", + "type": "timeseries" + }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 40 + "y": 46 }, "id": 15, "panels": [], @@ -955,7 +1091,7 @@ "h": 9, "w": 12, "x": 0, - "y": 41 + "y": 47 }, "id": 13, "options": { @@ -1081,7 +1217,7 @@ "h": 9, "w": 12, "x": 12, - "y": 41 + "y": 47 }, "id": 5, "options": { @@ -1200,7 +1336,7 @@ "h": 9, "w": 12, "x": 0, - "y": 50 + "y": 56 }, "id": 11, "options": { @@ -1326,7 +1462,7 @@ "h": 9, "w": 12, "x": 12, - "y": 50 + "y": 56 }, "id": 21, "options": { @@ -1444,6 +1580,6 @@ "timezone": "", "title": "KPI tracker", "uid": "8dm2sVA4k", - "version": 10, + "version": 12, "weekStart": "" } \ No newline at end of file diff --git a/kpi-tracker/resources/schema.sql b/kpi-tracker/resources/schema.sql index d16e807a..f116aadb 100644 --- a/kpi-tracker/resources/schema.sql +++ b/kpi-tracker/resources/schema.sql @@ -26,12 +26,18 @@ CREATE TABLE IF NOT EXISTS blocks ( id SERIAL8 PRIMARY KEY, hash BYTEA NOT NULL UNIQUE, timestamp INT8 NOT NULL, - height INT8 NOT NULL, - total_stake INT8 -- NULL means the block is NOT a payday block. + height INT8 NOT NULL ); -- Create index on block timestamp to improve performance when querying for blocks within a timerange. CREATE INDEX IF NOT EXISTS blocks_timestamp ON blocks (timestamp); +-- All payday blocks (only exists for protocol version 4 and onwards). +CREATE TABLE IF NOT EXISTS paydays ( + block INT8 PRIMARY KEY REFERENCES blocks(id) ON DELETE RESTRICT ON UPDATE RESTRICT, + total_stake INT8 NOT NULL, + num_bakers INT8 -- Only supported for protocol version 6 and onwards. +); + -- All accounts created. CREATE TABLE IF NOT EXISTS accounts ( id SERIAL8 PRIMARY KEY, diff --git a/kpi-tracker/src/main.rs b/kpi-tracker/src/main.rs index 58d086d3..59802b4f 100644 --- a/kpi-tracker/src/main.rs +++ b/kpi-tracker/src/main.rs @@ -103,10 +103,10 @@ struct BlockDetails { /// Height of block from genesis. Used to restart the process of collecting /// metrics from the latest block recorded. height: AbsoluteBlockHeight, - /// Total amount staked across all pools inclusive passive delegation. This - /// is only recorded for "payday" blocks reflected by `Some`, where non - /// payday blocks are reflected by `None`. - total_stake: Option, + /// [`PaydayBlockData`] for the block. This is only recorded for "payday" + /// blocks reflected by `Some`, where non payday blocks are reflected by + /// `None`. + payday_data: Option, } /// Holds selected attributes about accounts created on chain. @@ -204,6 +204,8 @@ enum BlockData { struct PreparedStatements { /// Insert block into DB insert_block: tokio_postgres::Statement, + /// Insert payday into DB + insert_payday: tokio_postgres::Statement, /// Insert account into DB insert_account: tokio_postgres::Statement, /// Insert contract module into DB @@ -230,10 +232,12 @@ impl PreparedStatements { async fn new(client: &tokio_postgres::Client) -> Result { let insert_block = client .prepare( - "INSERT INTO blocks (hash, timestamp, height, total_stake) VALUES ($1, $2, $3, \ - $4) RETURNING id", + "INSERT INTO blocks (hash, timestamp, height) VALUES ($1, $2, $3) RETURNING id", ) .await?; + let insert_payday = client + .prepare("INSERT INTO paydays (block, total_stake, num_bakers) VALUES ($1, $2, $3)") + .await?; let insert_account = client .prepare("INSERT INTO accounts (address, block, is_initial) VALUES ($1, $2, $3)") .await?; @@ -287,6 +291,7 @@ impl PreparedStatements { Ok(Self { insert_block, + insert_payday, insert_account, insert_contract_module, insert_contract_instance, @@ -305,14 +310,10 @@ impl PreparedStatements { block_hash: BlockHash, block_details: &BlockDetails, ) -> Result { - let total_stake = block_details - .total_stake - .map(|amount| (amount.micro_ccd() as i64)); - let values: [&(dyn ToSql + Sync); 4] = [ + let values: [&(dyn ToSql + Sync); 3] = [ &block_hash.as_ref(), &block_details.block_time.timestamp(), &(block_details.height.height as i64), - &total_stake, ]; let now = tokio::time::Instant::now(); @@ -320,6 +321,15 @@ impl PreparedStatements { let id = row.try_get::<_, i64>(0)?; log::trace!("Took {}ms to insert block.", now.elapsed().as_millis()); + if let Some(payday_data) = block_details.payday_data { + let values: [&(dyn ToSql + Sync); 3] = [ + &id, + &(payday_data.total_stake.micro_ccd() as i64), + &payday_data.baker_count, + ]; + db_tx.execute(&self.insert_payday, &values).await?; + } + Ok(id) } @@ -736,7 +746,7 @@ async fn process_chain_genesis_block( let block_details = BlockDetails { block_time: block_info.block_slot_time, height: block_info.block_height, - total_stake: None, + payday_data: None, }; let accounts = accounts_in_block(node, block_hash).await?; @@ -749,43 +759,56 @@ async fn process_chain_genesis_block( Ok(genesis_data) } +#[derive(Debug, Clone, Copy)] +struct PaydayBlockData { + total_stake: Amount, + /// The amount of active bakers. Only for >= protocol version 6. + baker_count: Option, +} + /// If block specified by `block_hash` is a payday block (also implies >= -/// protocol version 4), this returns the total stake for that block. Otherwise -/// returns `None`. -async fn p4_payday_total_stake( +/// protocol version 4), this returns [`PaydayBlockData`]. Otherwise, returns +/// `None`. +async fn process_payday_block( node: &mut Client, block_hash: BlockHash, -) -> anyhow::Result> { +) -> anyhow::Result> { + let is_payday_block = node + .is_payday_block(block_hash) + .await + .with_context(|| { + format!("Could not assert whether block is payday block for: {block_hash}") + })? + .response; + + if !is_payday_block { + return Ok(None); + } + let tokenomics_info = node .get_tokenomics_info(block_hash) .await - .with_context(|| format!("Could not get tokenomics info for block: {}", block_hash))? + .with_context(|| format!("Could not get tokenomics info for block: {block_hash}"))? .response; - if let RewardsOverview::V1 { + let RewardsOverview::V1 { total_staked_capital, .. - } = tokenomics_info - { - let is_payday_block = node - .is_payday_block(block_hash) - .await - .with_context(|| { - format!( - "Could not assert whether block is payday block for: {}", - block_hash - ) - })? - .response; - - if is_payday_block { - return Ok(Some(total_staked_capital)); - }; - + } = tokenomics_info else { return Ok(None); - } + }; + + // TODO: Concurrently query for bakers and total stake + let baker_count = match node.get_bakers_reward_period(block_hash).await { + Ok(bakers) => Some(bakers.response.count().await as i64), + // Error means protocol version < 6 + Err(_) => None, + }; - Ok(None) + Ok(Some(PaydayBlockData { + total_stake: total_staked_capital, + baker_count, + })) } /// Get `BlockDetails` for given block represented by `block_hash` @@ -799,11 +822,11 @@ async fn get_block_details( .with_context(|| format!("Could not get block info for block: {}", block_hash))? .response; - let total_stake = p4_payday_total_stake(node, block_hash).await?; + let payday_data = process_payday_block(node, block_hash).await?; let block_details = BlockDetails { block_time: block_info.block_slot_time, height: block_info.block_height, - total_stake, + payday_data, }; Ok(block_details)