From c1b5fa239a6965574fc78090f65a3581147abc49 Mon Sep 17 00:00:00 2001 From: Neotamandua <107320179+Neotamandua@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:52:48 +0100 Subject: [PATCH 1/3] node: add new migration with supply_info table --- node/migrations/20260130152449_supply_info.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 node/migrations/20260130152449_supply_info.sql diff --git a/node/migrations/20260130152449_supply_info.sql b/node/migrations/20260130152449_supply_info.sql new file mode 100644 index 0000000000..b346759126 --- /dev/null +++ b/node/migrations/20260130152449_supply_info.sql @@ -0,0 +1,15 @@ +-- Single-row table tracking current supply statistics +-- This table always contains exactly one row (id=1) that gets updated +CREATE TABLE IF NOT EXISTS supply_info ( + id INTEGER PRIMARY KEY NOT NULL CHECK (id = 1), -- Constrained to 1 to enforce single-row table + block_height INTEGER NOT NULL, -- Current block height of these stats + total_supply REAL NOT NULL, -- Total coins created minus burned coins (floating point) + circulating_supply REAL NOT NULL, -- Coins in public circulation (floating point) + max_supply REAL NOT NULL, -- Theoretical maximum coins that can exist minus burned (floating point) + burned REAL NOT NULL, -- Total coins verifiably burned (floating point) + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL -- Last update timestamp +); + +-- Insert the initial row with default values +INSERT INTO supply_info (id, block_height, total_supply, circulating_supply, max_supply, burned) +VALUES (1, 0, 500000000.0, 500000000.0, 1000000000.0, 0.0); From d2f587e81c7e4d7e6b9f85914fb58bb80e98a22e Mon Sep 17 00:00:00 2001 From: Neotamandua <107320179+Neotamandua@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:11:24 +0100 Subject: [PATCH 2/3] node: add supply stat tracking - Update query cache --- ...92ed42556487d0c87f490f50efb647df3d6fb.json | 12 + ...c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d.json | 12 + ...5a727222d9d2c9c4130070ba9a49ae7b91adc.json | 12 - ...bfaf689f8464a21c85b7131bf854f5d2b1bb7.json | 50 ++++ ...4cbdd960e3055e7fd762e7c02949be2ab8127.json | 20 ++ ...7cb140d750eff8405fda6b6fa18f75b18ad6.json} | 4 +- node/src/archive.rs | 1 + node/src/archive/sqlite.rs | 245 +++++++++++++++++- 8 files changed, 336 insertions(+), 20 deletions(-) create mode 100644 node/.sqlx/query-13807a5e27b376c2e9f7566d0ce92ed42556487d0c87f490f50efb647df3d6fb.json create mode 100644 node/.sqlx/query-57cb3510ebca13bbacf5aead1f7c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d.json delete mode 100644 node/.sqlx/query-787116727e409c76887216f51fb5a727222d9d2c9c4130070ba9a49ae7b91adc.json create mode 100644 node/.sqlx/query-abd18d06a7da9d6b3f2daa50050bfaf689f8464a21c85b7131bf854f5d2b1bb7.json create mode 100644 node/.sqlx/query-db2d15d15e28ea48fce2f4746d14cbdd960e3055e7fd762e7c02949be2ab8127.json rename node/.sqlx/{query-05069f1a3f24ca8607a183741620c053d0ef342fec427d3689d181acc8fa78d2.json => query-e2cc2eac87001edb496a1d6aa5e47cb140d750eff8405fda6b6fa18f75b18ad6.json} (50%) diff --git a/node/.sqlx/query-13807a5e27b376c2e9f7566d0ce92ed42556487d0c87f490f50efb647df3d6fb.json b/node/.sqlx/query-13807a5e27b376c2e9f7566d0ce92ed42556487d0c87f490f50efb647df3d6fb.json new file mode 100644 index 0000000000..a217057b4c --- /dev/null +++ b/node/.sqlx/query-13807a5e27b376c2e9f7566d0ce92ed42556487d0c87f490f50efb647df3d6fb.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "INSERT INTO unfinalized_blocks (block_height, block_hash)\n VALUES (?, ?)\n ON CONFLICT(block_height) DO UPDATE SET block_hash = excluded.block_hash", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "13807a5e27b376c2e9f7566d0ce92ed42556487d0c87f490f50efb647df3d6fb" +} diff --git a/node/.sqlx/query-57cb3510ebca13bbacf5aead1f7c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d.json b/node/.sqlx/query-57cb3510ebca13bbacf5aead1f7c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d.json new file mode 100644 index 0000000000..ef71d005f8 --- /dev/null +++ b/node/.sqlx/query-57cb3510ebca13bbacf5aead1f7c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "UPDATE supply_info\n SET block_height = ?,\n total_supply = ?,\n circulating_supply = ?,\n max_supply = ?,\n burned = ?,\n updated_at = CURRENT_TIMESTAMP\n WHERE id = 1", + "describe": { + "columns": [], + "parameters": { + "Right": 5 + }, + "nullable": [] + }, + "hash": "57cb3510ebca13bbacf5aead1f7c8cf72e468e23e8c2d1ce57df9a0f8ce2ae1d" +} diff --git a/node/.sqlx/query-787116727e409c76887216f51fb5a727222d9d2c9c4130070ba9a49ae7b91adc.json b/node/.sqlx/query-787116727e409c76887216f51fb5a727222d9d2c9c4130070ba9a49ae7b91adc.json deleted file mode 100644 index aa7f96b644..0000000000 --- a/node/.sqlx/query-787116727e409c76887216f51fb5a727222d9d2c9c4130070ba9a49ae7b91adc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO unfinalized_blocks (block_height, block_hash) \n VALUES (?, ?)\n ON CONFLICT(block_height) DO UPDATE SET block_hash = excluded.block_hash", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "787116727e409c76887216f51fb5a727222d9d2c9c4130070ba9a49ae7b91adc" -} diff --git a/node/.sqlx/query-abd18d06a7da9d6b3f2daa50050bfaf689f8464a21c85b7131bf854f5d2b1bb7.json b/node/.sqlx/query-abd18d06a7da9d6b3f2daa50050bfaf689f8464a21c85b7131bf854f5d2b1bb7.json new file mode 100644 index 0000000000..432de36ed5 --- /dev/null +++ b/node/.sqlx/query-abd18d06a7da9d6b3f2daa50050bfaf689f8464a21c85b7131bf854f5d2b1bb7.json @@ -0,0 +1,50 @@ +{ + "db_name": "SQLite", + "query": "SELECT block_height, total_supply, circulating_supply, max_supply, burned, updated_at as \"updated_at: String\"\n FROM supply_info\n WHERE id = 1", + "describe": { + "columns": [ + { + "name": "block_height", + "ordinal": 0, + "type_info": "Integer" + }, + { + "name": "total_supply", + "ordinal": 1, + "type_info": "Float" + }, + { + "name": "circulating_supply", + "ordinal": 2, + "type_info": "Float" + }, + { + "name": "max_supply", + "ordinal": 3, + "type_info": "Float" + }, + { + "name": "burned", + "ordinal": 4, + "type_info": "Float" + }, + { + "name": "updated_at: String", + "ordinal": 5, + "type_info": "Datetime" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false, + false, + false, + false, + false, + false + ] + }, + "hash": "abd18d06a7da9d6b3f2daa50050bfaf689f8464a21c85b7131bf854f5d2b1bb7" +} diff --git a/node/.sqlx/query-db2d15d15e28ea48fce2f4746d14cbdd960e3055e7fd762e7c02949be2ab8127.json b/node/.sqlx/query-db2d15d15e28ea48fce2f4746d14cbdd960e3055e7fd762e7c02949be2ab8127.json new file mode 100644 index 0000000000..6355f45fb6 --- /dev/null +++ b/node/.sqlx/query-db2d15d15e28ea48fce2f4746d14cbdd960e3055e7fd762e7c02949be2ab8127.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "SELECT total_supply FROM supply_info WHERE id = 1", + "describe": { + "columns": [ + { + "name": "total_supply", + "ordinal": 0, + "type_info": "Float" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + }, + "hash": "db2d15d15e28ea48fce2f4746d14cbdd960e3055e7fd762e7c02949be2ab8127" +} diff --git a/node/.sqlx/query-05069f1a3f24ca8607a183741620c053d0ef342fec427d3689d181acc8fa78d2.json b/node/.sqlx/query-e2cc2eac87001edb496a1d6aa5e47cb140d750eff8405fda6b6fa18f75b18ad6.json similarity index 50% rename from node/.sqlx/query-05069f1a3f24ca8607a183741620c053d0ef342fec427d3689d181acc8fa78d2.json rename to node/.sqlx/query-e2cc2eac87001edb496a1d6aa5e47cb140d750eff8405fda6b6fa18f75b18ad6.json index 6ed2804ec2..531fb6654b 100644 --- a/node/.sqlx/query-05069f1a3f24ca8607a183741620c053d0ef342fec427d3689d181acc8fa78d2.json +++ b/node/.sqlx/query-e2cc2eac87001edb496a1d6aa5e47cb140d750eff8405fda6b6fa18f75b18ad6.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT EXISTS(\n SELECT 1 \n FROM finalized_blocks \n WHERE block_hash = ?\n ) AS \"exists!: bool\"", + "query": "SELECT EXISTS(\n SELECT 1\n FROM finalized_blocks\n WHERE block_hash = ?\n ) AS \"exists!: bool\"", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "05069f1a3f24ca8607a183741620c053d0ef342fec427d3689d181acc8fa78d2" + "hash": "e2cc2eac87001edb496a1d6aa5e47cb140d750eff8405fda6b6fa18f75b18ad6" } diff --git a/node/src/archive.rs b/node/src/archive.rs index bfca032d99..aba4be7cd7 100644 --- a/node/src/archive.rs +++ b/node/src/archive.rs @@ -20,6 +20,7 @@ mod transformer; use conf::Params as ArchiveParams; pub use moonlight::{MoonlightGroup, Order}; +pub use sqlite::SupplyInfo; // Archive folder containing the sqlite database and the moonlight database const ARCHIVE_FOLDER_NAME: &str = "archive"; diff --git a/node/src/archive/sqlite.rs b/node/src/archive/sqlite.rs index b049c556fa..66de0e086a 100644 --- a/node/src/archive/sqlite.rs +++ b/node/src/archive/sqlite.rs @@ -9,6 +9,7 @@ use std::path::Path; use std::time::Duration; use anyhow::Result; +use dusk_core::{from_dusk, Dusk}; use node_data::events::contract::ContractTxEvent; use node_data::ledger::Hash; use sqlx::sqlite::{ @@ -18,11 +19,17 @@ use sqlx::sqlite::{ use sqlx::{Pool, Sqlite, SqliteConnection}; use tracing::{error, info, warn}; +pub use data::SupplyInfo; + use crate::archive::transformer; use crate::archive::Archive; /// The name of the archive SQLite database. const SQLITEARCHIVE_DB_NAME: &str = "archive.sqlite3"; +/// The initial supply for DUSK. +const INITIAL_SUPPLY: f64 = 500_000_000.0; +/// The maximum supply for DUSK. +const MAX_SUPPLY: f64 = 1_000_000_000.0; // The roles available for SQLite access. #[derive(Clone, Copy)] @@ -353,6 +360,21 @@ impl Archive { Ok((row.moonlight as u64, row.phoenix as u64)) } + + /// Fetch the supply info from the supply_info table + pub async fn fetch_supply_info(&self) -> Result { + let mut conn = self.sqlite_reader.acquire().await?; + + let supply_info = sqlx::query_as!(data::SupplyInfo, + r#"SELECT block_height, total_supply, circulating_supply, max_supply, burned, updated_at as "updated_at: String" + FROM supply_info + WHERE id = 1"# + ) + .fetch_one(&mut *conn) + .await?; + + Ok(supply_info) + } } /// Mutating methods for the SQLite Archive @@ -371,7 +393,7 @@ impl Archive { let hex_block_hash = hex::encode(block_hash); sqlx::query!( - r#"INSERT INTO unfinalized_blocks (block_height, block_hash) + r#"INSERT INTO unfinalized_blocks (block_height, block_hash) VALUES (?, ?) ON CONFLICT(block_height) DO UPDATE SET block_hash = excluded.block_hash"#, block_height, hex_block_hash @@ -407,9 +429,12 @@ impl Archive { /// Finalize all data related to the block of the given hash in the archive. /// - /// This also triggers the loading of the MoonlightTxEvents into the - /// moonlight db. This also updates the last finalized block height - /// attribute. + /// This also: + /// - Triggers the loading of the MoonlightTxEvents into the moonlight db. + /// - Updates the last finalized block height attribute. + /// - Includes phoenix presence in finalized_blocks table for the finalized + /// block. + /// - Updates circulating supply. pub(crate) async fn finalize_archive_data( &mut self, current_block_height: u64, @@ -424,8 +449,8 @@ impl Archive { // no write lock (yet). let already_finalized = sqlx::query_scalar!( r#"SELECT EXISTS( - SELECT 1 - FROM finalized_blocks + SELECT 1 + FROM finalized_blocks WHERE block_hash = ? ) AS "exists!: bool""#, hex_block_hash @@ -479,6 +504,67 @@ impl Archive { && event.event.topic == dusk_core::transfer::PHOENIX_TOPIC }); + /* + Get the reward event from the stake contract + that contains a Vec for all the rewards paid out in the block. + */ + let reward_event = events + .iter() + .find(|event| { + event.event.target == dusk_core::stake::STAKE_CONTRACT + && event.event.topic == "reward" + }) + .expect("Every block needs a reward event") + .event + .clone(); + + let rewards = rkyv::from_bytes::>( + &reward_event.data, + ) + .expect("Reward event should be rkyv deserializable"); + + let total_block_rewards: Dusk = rewards.iter().map(|r| r.value).sum(); + let total_block_rewards_f64: f64 = from_dusk(total_block_rewards); + + // Fetch the previous supply from the database + let previous_supply: f64 = sqlx::query_scalar!( + r#"SELECT total_supply FROM supply_info WHERE id = 1"# + ) + .fetch_one(&mut *tx) + .await?; + + // Calculate theoretical total supply based on emission schedule + let theoretical_total_supply = + util::calculate_total_supply(finalized_block_height as u64); + + // Actual supply is previous supply + what was emitted in this block + let actual_total_supply = previous_supply + total_block_rewards_f64; + + // Burned amount is the difference between theoretical and actual supply + // This accounts for any coins that were burned or failed to be minted + let burned = theoretical_total_supply - actual_total_supply; + + // Circulating supply equals actual total supply + let circulating_supply = actual_total_supply; + + sqlx::query!( + r#"UPDATE supply_info + SET block_height = ?, + total_supply = ?, + circulating_supply = ?, + max_supply = ?, + burned = ?, + updated_at = CURRENT_TIMESTAMP + WHERE id = 1"#, + finalized_block_height, + actual_total_supply, + circulating_supply, + MAX_SUPPLY, + burned + ) + .execute(&mut *tx) + .await?; + // Group events by origin (block height, OriginHash) let grouped_events = transformer::group_by_origins( events, @@ -545,6 +631,7 @@ impl Archive { } tx.commit().await?; + let current_block_height: i64 = current_block_height as i64; info!( "Marked block {} with height {} as finalized. After {} blocks at height {}", @@ -654,6 +741,17 @@ mod data { use serde::{Deserialize, Serialize}; use sqlx::FromRow; + /// Supply information data + #[derive(Debug, Clone, FromRow, Serialize, Deserialize)] + pub struct SupplyInfo { + pub block_height: i64, + pub total_supply: f64, + pub circulating_supply: f64, + pub max_supply: f64, + pub burned: f64, + pub updated_at: String, + } + /// Data transfer object for GraphQL pagination #[serde_with::serde_as] #[derive(Debug, Clone, FromRow, Serialize, Deserialize)] @@ -721,6 +819,8 @@ mod data { } mod util { + use super::INITIAL_SUPPLY; + /// Truncate a string to at most 35 characters. pub(super) fn truncate_string(s: &str) -> String { if s.len() <= 35 { @@ -737,6 +837,139 @@ mod util { .rev() .collect::() } + + /// Calculate the theoretical optimistic total supply at a given block + /// height. + /// + /// This represents what the supply should be if no coins were burned during + /// emission. + pub fn calculate_total_supply(block_height: u64) -> f64 { + const PERIOD_BLOCKS: u64 = 12_614_400; + + // Emission per complete period in Dusk + const P_1_EMISSION: f64 = 250_480_000.0; + const P_2_EMISSION: f64 = 125_240_000.0; + const P_3_EMISSION: f64 = 62_620_000.0; + const P_4_EMISSION: f64 = 31_310_000.0; + const P_5_EMISSION: f64 = 15_650_000.0; + const P_6_EMISSION: f64 = 7_830_000.0; + const P_7_EMISSION: f64 = 3_910_000.0; + const P_8_EMISSION: f64 = 1_950_000.0; + const P_9_EMISSION: f64 = 980_000.0; + const FINAL_MINT: f64 = 0.05428; + + let total_emission = match block_height { + 0 => 0.0, + 1..=12_614_400 => { + // Period 1: partial or complete + (block_height as f64 / PERIOD_BLOCKS as f64) * P_1_EMISSION + } + 12_614_401..=25_228_800 => { + // Period 1 complete + Period 2 partial + let remaining = block_height - 12_614_400; + P_1_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_2_EMISSION + } + 25_228_801..=37_843_200 => { + // Periods 1-2 complete + Period 3 partial + let remaining = block_height - 25_228_800; + P_1_EMISSION + + P_2_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_3_EMISSION + } + 37_843_201..=50_457_600 => { + // Periods 1-3 complete + Period 4 partial + let remaining = block_height - 37_843_200; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_4_EMISSION + } + 50_457_601..=63_072_000 => { + // Periods 1-4 complete + Period 5 partial + let remaining = block_height - 50_457_600; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_5_EMISSION + } + 63_072_001..=75_686_400 => { + // Periods 1-5 complete + Period 6 partial + let remaining = block_height - 63_072_000; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_6_EMISSION + } + 75_686_401..=88_300_800 => { + // Periods 1-6 complete + Period 7 partial + let remaining = block_height - 75_686_400; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + P_6_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_7_EMISSION + } + 88_300_801..=100_915_200 => { + // Periods 1-7 complete + Period 8 partial + let remaining = block_height - 88_300_800; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + P_6_EMISSION + + P_7_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_8_EMISSION + } + 100_915_201..=113_529_596 => { + // Periods 1-8 complete + Period 9 partial + let remaining = block_height - 100_915_200; + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + P_6_EMISSION + + P_7_EMISSION + + P_8_EMISSION + + (remaining as f64 / PERIOD_BLOCKS as f64) * P_9_EMISSION + } + 113_529_597 => { + // All periods complete + final mint + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + P_6_EMISSION + + P_7_EMISSION + + P_8_EMISSION + + P_9_EMISSION + + FINAL_MINT + } + _ => { + // Beyond last mint - max emission reached + P_1_EMISSION + + P_2_EMISSION + + P_3_EMISSION + + P_4_EMISSION + + P_5_EMISSION + + P_6_EMISSION + + P_7_EMISSION + + P_8_EMISSION + + P_9_EMISSION + + FINAL_MINT + } + }; + + INITIAL_SUPPLY + total_emission + } } #[cfg(test)] From 454d9601fc2485b66cd4530633cf55c67cc1243b Mon Sep 17 00:00:00 2001 From: Neotamandua <107320179+Neotamandua@users.noreply.github.com> Date: Fri, 30 Jan 2026 20:44:08 +0100 Subject: [PATCH 3/3] rusk: expose supply gql endpoint --- rusk/src/lib/http/chain/graphql.rs | 12 +++++++ .../lib/http/chain/graphql/archive/data.rs | 35 ++++++++++++++++++- .../chain/graphql/archive/finalized_block.rs | 3 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/rusk/src/lib/http/chain/graphql.rs b/rusk/src/lib/http/chain/graphql.rs index 4ca3296f8b..89dbddc3ee 100644 --- a/rusk/src/lib/http/chain/graphql.rs +++ b/rusk/src/lib/http/chain/graphql.rs @@ -300,4 +300,16 @@ impl Query { Ok(next_height) } + + #[cfg(feature = "archive")] + pub async fn supply_stats( + &self, + ctx: &Context<'_>, + ) -> FieldResult { + let (_, archive) = ctx.data::()?; + + let supply_stats = archive.fetch_supply_info().await?; + + Ok(SupplyStats(supply_stats)) + } } diff --git a/rusk/src/lib/http/chain/graphql/archive/data.rs b/rusk/src/lib/http/chain/graphql/archive/data.rs index 9662268346..049cac6b60 100644 --- a/rusk/src/lib/http/chain/graphql/archive/data.rs +++ b/rusk/src/lib/http/chain/graphql/archive/data.rs @@ -7,10 +7,43 @@ use async_graphql::Object; use dusk_bytes::Serializable; use dusk_core::signatures::bls::PublicKey as AccountPublicKey; -use node::archive::MoonlightGroup; +use node::archive::{MoonlightGroup, SupplyInfo}; use serde::Serialize; use translator::{IntermediateEvent, IntermediateMoonlightGroup}; +pub struct SupplyStats(pub SupplyInfo); + +#[Object] +impl SupplyStats { + pub async fn json(&self) -> serde_json::Value { + serde_json::to_value(&self.0).unwrap_or_default() + } + + pub async fn block_height(&self) -> i64 { + self.0.block_height + } + + pub async fn total_supply(&self) -> f64 { + self.0.total_supply + } + + pub async fn circulating_supply(&self) -> f64 { + self.0.circulating_supply + } + + pub async fn max_supply(&self) -> f64 { + self.0.max_supply + } + + pub async fn burned(&self) -> f64 { + self.0.burned + } + + pub async fn updated_at(&self) -> String { + self.0.updated_at.clone() + } +} + /// List of archived transactions where each transaction includes at least one /// event indicating a Moonlight transfer of funds (Not necessarily a moonlight /// transaction). diff --git a/rusk/src/lib/http/chain/graphql/archive/finalized_block.rs b/rusk/src/lib/http/chain/graphql/archive/finalized_block.rs index 3eef204f67..4707b02705 100644 --- a/rusk/src/lib/http/chain/graphql/archive/finalized_block.rs +++ b/rusk/src/lib/http/chain/graphql/archive/finalized_block.rs @@ -6,9 +6,10 @@ //! Module for GraphQL that only pertains to finalized blocks. -use crate::http::chain::graphql::DBContext; use async_graphql::{Context, FieldError, FieldResult}; +use crate::http::chain::graphql::DBContext; + /// Check if a block height matches a block hash for a finalized block. pub async fn check_finalized_block( ctx: &Context<'_>,