[−][src]Module exonum_explorer_service::api
HTTP API for the explorer service. All APIs are accessible from the public HTTP server of the node.
Table of Contents
-
Call status:
List Blocks
Property | Value |
---|---|
Path | /api/explorer/v1/blocks |
Method | GET |
Query type | BlockQuery |
Return type | BlockInfo |
Returns the explored range and the corresponding headers. The range specifies the smallest and largest heights traversed to collect the blocks.
let mut testkit = TestKitBuilder::validator() .with_default_rust_service(ExplorerFactory) .build(); testkit.create_blocks_until(Height(5)); let api = testkit.api(); let response: BlocksRange = reqwest::Client::new() .get(&api.public_url("api/explorer/v1/blocks?count=2")) .send()? .error_for_status()? .json()?; assert_eq!(response.range, Height(4)..Height(6)); // Blocks are returned in reverse order, from the latest // to the earliest. assert_eq!(response.blocks[0].block.height, Height(5)); assert_eq!(response.blocks[1].block.height, Height(4));
Get Specific Block
Property | Value |
---|---|
Path | /api/explorer/v1/block |
Method | GET |
Query type | BlockQuery |
Return type | BlockInfo |
Returns the content for a block at a specific height
.
testkit.create_blocks_until(Height(5)); let api = testkit.api(); let response: BlockInfo = reqwest::Client::new() .get(&api.public_url("api/explorer/v1/block?height=3")) .send()? .error_for_status()? .json()?; assert_eq!(response.block.height, Height(3)); // Precommits and median precommit time are always returned. assert!(response.precommits.is_some()); assert!(response.time.is_some());
Transaction by Hash
Property | Value |
---|---|
Path | /api/explorer/v1/transactions |
Method | GET |
Query type | TransactionQuery |
Return type | TransactionInfo |
Searches for a transaction, either committed or uncommitted, by the hash.
#[exonum_interface] trait ServiceInterface<Ctx> { type Output; #[interface_method(id = 0)] fn do_nothing(&self, ctx: Ctx, _seed: u32) -> Self::Output; } #[derive(Debug, ServiceDispatcher, ServiceFactory)] #[service_dispatcher(implements("ServiceInterface"))] struct MyService; // Some implementations skipped for `MyService`... let mut testkit = TestKitBuilder::validator() .with_default_rust_service(ExplorerFactory) .with_default_rust_service(MyService) .build(); let tx = gen_keypair().do_nothing(MyService::INSTANCE_ID, 0); testkit.create_block_with_transaction(tx.clone()); let api = testkit.api(); let response: TransactionInfo = reqwest::Client::new() .get(&api.public_url("api/explorer/v1/transactions")) .query(&TransactionQuery { hash: tx.object_hash() }) .send()? .error_for_status()? .json()?; let response = response.as_committed().unwrap(); assert_eq!(response.location().block_height(), Height(1));
Call Status for Transaction
Property | Value |
---|---|
Path | /api/explorer/v1/call_status/transaction |
Method | GET |
Query type | TransactionQuery |
Return type | CallStatusResponse |
Returns call status of committed transaction.
#[exonum_interface] trait ServiceInterface<Ctx> { type Output; #[interface_method(id = 0)] fn cause_error(&self, ctx: Ctx, _seed: u32) -> Self::Output; } #[derive(Debug, ServiceDispatcher, ServiceFactory)] #[service_dispatcher(implements("ServiceInterface"))] struct MyService; // Some implementations skipped for `MyService`... let mut testkit = TestKitBuilder::validator() .with_default_rust_service(MyService) .with_default_rust_service(ExplorerFactory) .build(); let tx = gen_keypair().cause_error(MyService::INSTANCE_ID, 0); testkit.create_block_with_transaction(tx.clone()); let api = testkit.api(); let response: CallStatusResponse = reqwest::Client::new() .get(&api.public_url("api/explorer/v1/call_status/transaction")) .query(&TransactionQuery { hash: tx.object_hash() }) .send()? .error_for_status()? .json()?; let err = response.status.0.unwrap_err(); assert_eq!(err.description(), "Error!");
Call Status for before_transactions
hook
Property | Value |
---|---|
Path | /api/explorer/v1/call_status/before_transactions |
Method | GET |
Query type | CallStatusQuery |
Return type | CallStatusResponse |
Returns call status of a before_transactions
hook for a specific service at a specific height.
Note that the endpoint returns the normal execution status Ok(())
if the queried service
was not active at the specified height.
#[derive(Debug, ServiceDispatcher, ServiceFactory)] struct MyService; // Some implementations skipped for `MyService`... let mut testkit = TestKitBuilder::validator() .with_default_rust_service(MyService) .with_default_rust_service(ExplorerFactory) .build(); testkit.create_blocks_until(Height(5)); let api = testkit.api(); let response: CallStatusResponse = reqwest::Client::new() .get(&api.public_url("api/explorer/v1/call_status/before_transactions")) .query(&CallStatusQuery { height: Height(2), service_id: MyService::INSTANCE_ID, }) .send()? .error_for_status()? .json()?; let err = response.status.0.unwrap_err(); assert_eq!(err.description(), "Not a good start");
Call Status for after_transactions
hook
Property | Value |
---|---|
Path | /api/explorer/v1/call_status/after_transactions |
Method | GET |
Query type | CallStatusQuery |
Return type | CallStatusResponse |
Same as the previous endpoint, only for a hook executing after all transactions in a block.
Submit Transaction
Property | Value |
---|---|
Path | /api/explorer/v1/transactions |
Method | POST |
Query type | TransactionHex |
Return type | TransactionResponse |
Adds transaction into the pool of unconfirmed transactions if it is valid and returns an error otherwise.
#[exonum_interface] trait ServiceInterface<Ctx> { type Output; #[interface_method(id = 0)] fn do_nothing(&self, ctx: Ctx, _seed: u32) -> Self::Output; } #[derive(Debug, ServiceDispatcher, ServiceFactory)] #[service_dispatcher(implements("ServiceInterface"))] struct MyService; // Some implementations skipped for `MyService`... let mut testkit = TestKitBuilder::validator() .with_default_rust_service(ExplorerFactory) .with_default_rust_service(MyService) .build(); let tx = gen_keypair().do_nothing(MyService::INSTANCE_ID, 0); let tx_body = hex::encode(tx.to_bytes()); let api = testkit.api(); let response: TransactionResponse = reqwest::Client::new() .post(&api.public_url("api/explorer/v1/transactions")) .json(&TransactionHex { tx_body }) .send()? .error_for_status()? .json()?; assert_eq!(response.tx_hash, tx.object_hash());
Modules
websocket | WebSocket API of the explorer service. |
Structs
BlockInfo | Information about a block in the blockchain. |
BlockQuery | Block query parameters. |
BlocksQuery | Blocks in range parameters. |
BlocksRange | Information on blocks coupled with the corresponding range in the blockchain. |
CallStatusQuery | Query parameters to check the execution status of a |
CallStatusResponse | Call status response. |
CommittedTransactionSummary | Summary about a particular transaction in the blockchain. Does not include transaction content. |
TransactionFilter | Filter for transactions by service instance and (optionally) method identifier within the service. |
TransactionHex | Raw Transaction in hex representation. |
TransactionQuery | Transaction query parameters. |
TransactionResponse | Response to a request to broadcast a transaction over the blockchain network. |
Enums
Notification | Notification message passed to WebSocket clients. |
SubscriptionType | Subscription type for new blocks or committed transactions. |
TransactionInfo | Information about the transaction. |
Constants
MAX_BLOCKS_PER_REQUEST | The maximum number of blocks to return per blocks request, in this way the parameter limits the maximum execution time for such requests. |