mod.rs

Overview

This file defines the BlockchainQuery struct and implements its GraphQL query interface for accessing blockchain-related data such as accounts, blocks, messages, transactions, and their paginated collections. It provides asynchronous methods to fetch detailed blockchain entities, support cursor-based pagination, and resolve nested relationships between blockchain objects using DataLoader for efficient batching and caching.

The file organizes blockchain API queries in a GraphQL schema context, leveraging several submodules (account, blocks, transactions) that encapsulate domain-specific queries and types. It interacts heavily with the database layer (db module), GraphQL extensions, and asynchronous data loaders.


Modules


Struct: BlockchainQuery<'a>

Represents the root GraphQL query object for blockchain-related data. It holds a reference to the GraphQL Context which provides access to dependencies such as database connection pools and DataLoader instances.

Fields:

Field

Type

Description

ctx

&'a Context<'a>

Reference to the GraphQL query context.


Implementation of BlockchainQuery

The GraphQL query methods are implemented using the #[Object] macro from async_graphql. Each method corresponds to a GraphQL query node or connection, returning blockchain entities or paginated lists.

Method: account

async fn account(&self, address: String) -> Option<BlockchainAccountQuery<'_>>
query {
  blockchain {
    account(address: "0x123...") {
      // fields from BlockchainAccountQuery
    }
  }
}

Method: accounts

async fn accounts(
    &self,
    code_hash: Option<String>,
    first: Option<i32>,
    after: Option<String>,
    last: Option<i32>,
    before: Option<String>,
) -> Option<Connection<...>>
query {
  blockchain {
    accounts(first: 10, after: "cursor") {
      edges {
        node {
          address
          // other account fields
        }
      }
      pageInfo {
        hasNextPage
        hasPreviousPage
      }
    }
  }
}

Method: block

async fn block(&self, hash: String) -> Option<BlockchainBlock>
query {
  blockchain {
    block(hash: "blockhash") {
      chainOrder
      outMessages {
        id
        // other message fields
      }
    }
  }
}

Method: blocks

async fn blocks(
    &self,
    _allow_latest_inconsistent_data: Option<bool>,
    block_seq_no_range: Option<BlockchainMasterSeqNoFilter>,
    min_tr_count: Option<i32>,
    max_tr_count: Option<i32>,
    first: Option<i32>,
    after: Option<String>,
    last: Option<i32>,
    before: Option<String>,
) -> Option<Connection<...>>
query {
  blockchain {
    blocks(first: 5, after: "cursor") {
      edges {
        node {
          chainOrder
          trCount
        }
      }
      pageInfo {
        hasNextPage
      }
    }
  }
}

Method: message

async fn message(&self, hash: String) -> Option<BlockchainMessage>
query {
  blockchain {
    message(hash: "msghash") {
      body
      srcTransaction {
        id
      }
      dstTransaction {
        id
      }
    }
  }
}

Method: transaction

async fn transaction(&self, hash: String) -> Option<BlockchainTransaction>
query {
  blockchain {
    transaction(hash: "txhash") {
      id
      inMessage {
        id
      }
      outMessages {
        id
      }
    }
  }
}

Method: transactions

async fn transactions(
    &self,
    _allow_latest_inconsistent_data: Option<bool>,
    min_balance_delta: Option<String>,
    max_balance_delta: Option<String>,
    code_hash: Option<String>,
    first: Option<i32>,
    after: Option<String>,
    last: Option<i32>,
    before: Option<String>,
) -> Option<Connection<...>>
query {
  blockchain {
    transactions(first: 20) {
      edges {
        node {
          id
          inMessage {
            id
          }
          outMessages {
            id
          }
        }
      }
      pageInfo {
        hasPreviousPage
        hasNextPage
      }
    }
  }
}

Important Implementation Details


Interactions with Other System Components


Visual Diagram: Structure of BlockchainQuery and Relationships

classDiagram
class BlockchainQuery {
+ctx: Context
+account(address)
+accounts(filter, pagination)
+block(hash)
+blocks(filter, pagination)
+message(hash)
+transaction(hash)
+transactions(filter, pagination)
}
BlockchainQuery --> BlockchainAccountQuery : account()
BlockchainQuery --> BlockchainBlock : block()
BlockchainQuery --> BlockchainTransaction : transaction()
BlockchainQuery --> BlockchainMessage : message()
BlockchainQuery --> Connection : accounts(), blocks(), transactions()
BlockchainBlock --> MessageLoader : loads out_messages
BlockchainTransaction --> MessageLoader : loads in_message, out_messages
BlockchainMessage --> TransactionLoader : loads src_transaction, dst_transaction

This diagram presents the BlockchainQuery as the central query interface with methods returning blockchain entities or paginated connections. It shows the use of DataLoader instances to resolve nested relationships efficiently.