Skip to content
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

feat: add api endpoint to retrieve messages by nonce #1613

Merged
merged 6 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Description of the upcoming release here.

### Changed

- [#1613](https://github.com/FuelLabs/fuel-core/pull/1613): Add api endpoint to retrieve a message by its nonce
- [#1597](https://github.com/FuelLabs/fuel-core/pull/1597): Unify namespacing for `libp2p` modules
- [#1591](https://github.com/FuelLabs/fuel-core/pull/1591): Simplify libp2p dependencies and not depend on all sub modules directly.
- [#1590](https://github.com/FuelLabs/fuel-core/pull/1590): Use `AtomicView` in the `TxPool` to read the state of the database during insertion of the transactions.
Expand Down Expand Up @@ -287,4 +288,4 @@ FuelVM received a lot of safety and stability improvements:
- [#1484](https://github.com/FuelLabs/fuel-core/pull/1484): Removed `--network` CLI argument. Now the name of the network is fetched form chain configuration.
- [#1399](https://github.com/FuelLabs/fuel-core/pull/1399): Removed `relayer-da-finalization` parameter from the relayer CLI.
- [#1338](https://github.com/FuelLabs/fuel-core/pull/1338): Updated GraphQL client to use `DependentCost` for `k256`, `mcpi`, `s256`, `scwq`, `swwq` opcodes.
- [#1322](https://github.com/FuelLabs/fuel-core/pull/1322): The `manual_blocks_enabled` flag is removed from the CLI. The analog is a `debug` flag.
- [#1322](https://github.com/FuelLabs/fuel-core/pull/1322): The `manual_blocks_enabled` flag is removed from the CLI. The analog is a `debug` flag.
1 change: 1 addition & 0 deletions crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,7 @@ type Query {
contractBalance(contract: ContractId!, asset: AssetId!): ContractBalance!
contractBalances(filter: ContractBalanceFilterInput!, first: Int, after: String, last: Int, before: String): ContractBalanceConnection!
nodeInfo: NodeInfo!
message(nonce: Nonce!): Message
messages(owner: Address, first: Int, after: String, last: Int, before: String): MessageConnection!
messageProof(transactionId: TransactionId!, nonce: Nonce!, commitBlockId: BlockId, commitBlockHeight: U32): MessageProof
messageStatus(nonce: Nonce!): MessageStatus!
Expand Down
14 changes: 13 additions & 1 deletion crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ use types::{

use self::schema::{
block::ProduceBlockArgs,
message::MessageProofArgs,
message::{
MessageProofArgs,
NonceArgs,
},
};

pub mod pagination;
Expand Down Expand Up @@ -898,6 +901,15 @@ impl FuelClient {
Ok(balances)
}

// Retrieve a message by its nonce
pub async fn message(&self, nonce: &Nonce) -> io::Result<Option<types::Message>> {
let query = schema::message::MessageQuery::build(NonceArgs {
nonce: (*nonce).into(),
});
let message = self.query(query).await?.message.map(Into::into);
Ok(message)
}

pub async fn messages(
&self,
owner: Option<&Address>,
Expand Down
16 changes: 16 additions & 0 deletions crates/client/src/client/schema/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ pub struct Message {
pub da_height: U64,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct NonceArgs {
pub nonce: Nonce,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(
schema_path = "./assets/schema.sdl",
graphql_type = "Query",
variables = "NonceArgs"
)]
pub struct MessageQuery {
#[arguments(nonce: $nonce)]
pub message: Option<Message>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct MessageStatus {
Expand Down
11 changes: 11 additions & 0 deletions crates/fuel-core/src/schema/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
database::ReadView,
ports::DatabaseBlocks,
},
graphql_api::IntoApiResult,
query::MessageQueryData,
schema::scalars::{
BlockId,
Expand Down Expand Up @@ -66,6 +67,16 @@ pub struct MessageQuery {}

#[Object]
impl MessageQuery {
async fn message(
&self,
ctx: &Context<'_>,
#[graphql(desc = "The Nonce of the message")] nonce: Nonce,
) -> async_graphql::Result<Option<Message>> {
let query: &ReadView = ctx.data_unchecked();
let nonce = nonce.0;
query.message(&nonce).into_api_result()
}

async fn messages(
&self,
ctx: &Context<'_>,
Expand Down
45 changes: 45 additions & 0 deletions tests/tests/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,48 @@ fn verify_merkle<D: AsRef<[u8]>>(
let set: Vec<_> = set.iter().map(|bytes| *bytes.deref()).collect();
fuel_merkle::binary::verify(root.deref(), data, &set, index, leaf_count)
}

#[tokio::test]
async fn can_get_message() {
// create an owner
let owner = Address::new([1; 32]);

// create some messages for the owner
let first_msg = MessageConfig {
recipient: owner,
nonce: 1.into(),
..Default::default()
};

// configure the messges
let mut config = Config::local_node();
config.chain_conf.initial_state = Some(StateConfig {
messages: Some(vec![first_msg.clone()]),
..Default::default()
});

// setup service and client
let service = FuelService::new_node(config).await.unwrap();
let client = FuelClient::from(service.bound_address);

// run test
let message_response = client.message(&first_msg.nonce).await.unwrap();
assert!(message_response.is_some());
if let Some(message_response) = message_response {
assert_eq!(message_response.nonce, first_msg.nonce);
}
}

#[tokio::test]
async fn can_get_empty_message() {
let mut config = Config::local_node();
config.chain_conf.initial_state = Some(StateConfig {
..Default::default()
});

let service = FuelService::new_node(config).await.unwrap();
let client = FuelClient::from(service.bound_address);

let message_response = client.message(&1.into()).await.unwrap();
assert!(message_response.is_none());
}
Loading