-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add GraphQL extension to provide current STF and CP versions #2715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
cc4e8c2
3b48d47
9bd97b7
ac861c4
c022ba7
56d4c57
51237b3
335b243
946e315
2616cd7
da57953
2772ba7
3359d61
d51222f
5c24c74
bd610e7
3f3e971
c3c0148
ef9c445
b861a51
0b27037
946fc41
accfae0
4cd21b4
bbecdb8
e0f21bf
6d1ec52
3f32362
d8ea573
69b0da5
3aa2d2d
e03baac
932a1c5
ed1dd26
bfc5f58
03f9645
b44cac9
9c963d5
2d682fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| pub(crate) mod current_consensus_parameters_version; | ||
| pub(crate) mod current_stf_version; | ||
| pub(crate) mod required_fuel_block_height; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use crate::graphql_api::api_service::ConsensusProvider; | ||
| use async_graphql::{ | ||
| extensions::{ | ||
| Extension, | ||
| ExtensionContext, | ||
| ExtensionFactory, | ||
| NextExecute, | ||
| }, | ||
| Response, | ||
| Value, | ||
| }; | ||
|
|
||
| const CURRENT_CONSENSUS_PARAMETERS_VERSION: &str = "current_consensus_parameters_version"; | ||
|
|
||
| /// The extension to attach the current STF version to all responses. | ||
| #[derive(Debug, derive_more::Display, derive_more::From)] | ||
| pub(crate) struct CurrentConsensusParametersVersionExtension; | ||
| impl CurrentConsensusParametersVersionExtension { | ||
| pub fn new() -> Self { | ||
| Self | ||
| } | ||
| } | ||
|
|
||
| impl ExtensionFactory for CurrentConsensusParametersVersionExtension { | ||
| fn create(&self) -> Arc<dyn Extension> { | ||
| Arc::new(CurrentConsensusParametersVersionExtension::new()) | ||
| } | ||
| } | ||
|
|
||
| #[async_trait::async_trait] | ||
| impl Extension for CurrentConsensusParametersVersionExtension { | ||
| async fn execute( | ||
| &self, | ||
| ctx: &ExtensionContext<'_>, | ||
| operation_name: Option<&str>, | ||
| next: NextExecute<'_>, | ||
| ) -> Response { | ||
| let consensus_parameters_provider = ctx.data_unchecked::<ConsensusProvider>(); | ||
|
|
||
| let current_consensus_parameters_version = | ||
| consensus_parameters_provider.latest_consensus_parameters_version(); | ||
|
|
||
| let mut response = next.run(ctx, operation_name).await; | ||
acerone85 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| response.extensions.insert( | ||
| CURRENT_CONSENSUS_PARAMETERS_VERSION.to_string(), | ||
| Value::Number(current_consensus_parameters_version.into()), | ||
| ); | ||
| response | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use async_graphql::{ | ||
| extensions::{ | ||
| Extension, | ||
| ExtensionContext, | ||
| ExtensionFactory, | ||
| NextExecute, | ||
| }, | ||
| Response, | ||
| Value, | ||
| }; | ||
|
|
||
| use crate::graphql_api::database::ReadDatabase; | ||
|
|
||
| const CURRENT_STF_VERSION: &str = "current_stf_version"; | ||
|
|
||
| /// The extension to attach the current STF version to all responses. | ||
| #[derive(Debug, derive_more::Display, derive_more::From)] | ||
| pub(crate) struct CurrentStfVersionExtension; | ||
| impl CurrentStfVersionExtension { | ||
| pub fn new() -> Self { | ||
| Self | ||
| } | ||
| } | ||
|
|
||
| impl ExtensionFactory for CurrentStfVersionExtension { | ||
| fn create(&self) -> Arc<dyn Extension> { | ||
| Arc::new(CurrentStfVersionExtension::new()) | ||
| } | ||
| } | ||
|
|
||
| #[async_trait::async_trait] | ||
| impl Extension for CurrentStfVersionExtension { | ||
| async fn execute( | ||
| &self, | ||
| ctx: &ExtensionContext<'_>, | ||
| operation_name: Option<&str>, | ||
| next: NextExecute<'_>, | ||
| ) -> Response { | ||
| let db = ctx.data_unchecked::<ReadDatabase>(); | ||
|
|
||
| let mut response = next.run(ctx, operation_name).await; | ||
| if let Ok(view) = db.view() { | ||
| if let Ok(latest_block) = view.latest_block() { | ||
| let current_stf_version = | ||
| latest_block.header().state_transition_bytecode_version(); | ||
| response.extensions.insert( | ||
| CURRENT_STF_VERSION.to_string(), | ||
| Value::Number(current_stf_version.into()), | ||
| ); | ||
| } | ||
| } | ||
|
||
|
|
||
| response | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| use fuel_core::service::Config; | ||
| use fuel_core_bin::FuelService; | ||
| use serde_json::Value; | ||
| use test_helpers::send_graph_ql_query; | ||
|
|
||
| // TODO[RC]: Provide more detailed tests to verify that the correct STF and CP versions | ||
| // are returned. | ||
|
|
||
| #[tokio::test] | ||
| async fn extension_fields_are_present() { | ||
| const REQUIRED_FIELDS: [&str; 3] = [ | ||
| "current_stf_version", | ||
| "current_fuel_block_height", | ||
| "current_consensus_parameters_version", | ||
| ]; | ||
|
|
||
| let node = FuelService::new_node(Config::local_node()).await.unwrap(); | ||
| let url = format!("http://{}/v1/graphql", node.bound_address); | ||
|
|
||
| // Given | ||
| const QUERY: &str = r#" | ||
| query { | ||
| nodeInfo { | ||
| nodeVersion | ||
| } | ||
| } | ||
| "#; | ||
|
|
||
| // When | ||
| let response = send_graph_ql_query(&url, QUERY).await; | ||
|
|
||
| // Then | ||
| let json_value: Value = | ||
| serde_json::from_str(&response).expect("should be valid json"); | ||
| let extensions = json_value | ||
| .get("extensions") | ||
| .expect("should have extensions"); | ||
| for field in REQUIRED_FIELDS.iter() { | ||
| let is_field_present = extensions.get(field).is_some(); | ||
| assert!(is_field_present) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think spawning a separate extension for the field it is too overkill=D It decreases performance without any reason
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can have one extension fully dedicated to return information to the end user. Like STFV, CPV, current block height(we can remove setting of the current height from the
RequiredFuelBlockHeightExtension).In this case we will have one extension that we can use to add any metadata
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following changes have been made: