Skip to content

Commit

Permalink
explorer: Replace legacy event system with RUES
Browse files Browse the repository at this point in the history
  • Loading branch information
HDauven committed Jan 25, 2025
1 parent 2d865d1 commit 01265e3
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 25 deletions.
9 changes: 7 additions & 2 deletions explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Added

### Changed

- Replace legacy event system with RUES [#3425]

### Removed

- Remove version number from app title [#3338]
Expand Down Expand Up @@ -59,7 +62,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Change `raw` payload to `json` in transaction details [#2364]
- Change average gas price display value to “lux” [#2416]
- Update blocks table headers – `FEE` to `GAS`, `AVG` to `AVG PRICE`, and `TOTAL` to `USED` [#2416]
- Update blocks table headers – `FEE` to `GAS`, `AVG` to `AVG PRICE`, and
`TOTAL` to `USED` [#2416]
- Update block rewards tooltip information [#2166]
- Hide "Show More" button when error occurs [#2585]
- Update footer layout [#2640]
Expand Down Expand Up @@ -143,6 +147,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#3305]: https://github.com/dusk-network/rusk/issues/3305
[#3338]: https://github.com/dusk-network/rusk/issues/3338
[#3377]: https://github.com/dusk-network/rusk/issues/3377
[#3425]: https://github.com/dusk-network/rusk/issues/3425

<!-- VERSIONS -->

Expand Down
34 changes: 17 additions & 17 deletions explorer/src/lib/services/__tests__/duskAPI.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe("duskAPI", () => {
};

/** @type {URL} */
const gqlExpectedURL = new URL("/02/Chain", node);
const gqlExpectedURL = new URL("/on/graphql/query", node);
const endpointEnvName = "VITE_API_ENDPOINT";

/** @type {(data: Record<string | number, any> | number) => Response} */
Expand Down Expand Up @@ -72,7 +72,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n \\n\\nfragment TransactionInfo on SpentTransaction {\\n\\tblockHash,\\n\\tblockHeight,\\n\\tblockTimestamp,\\n err,\\n\\tgasSpent,\\n\\tid,\\n tx {\\n callData {\\n contractId,\\n data,\\n fnName\\n },\\n gasLimit,\\n gasPrice,\\n id,\\n isDeploy,\\n memo,\\n txType\\n }\\n}\\n\\nfragment BlockInfo on Block {\\n header {\\n hash,\\n gasLimit,\\n height,\\n prevBlockHash,\\n seed,\\n stateHash,\\n timestamp,\\n version\\n },\\n fees,\\n gasSpent,\\n reward,\\n transactions {...TransactionInfo}\\n}\\n\\n query($id: String!) { block(hash: $id) {...BlockInfo} }\\n ","topic":"gql"}",
"body": "fragment TransactionInfo on SpentTransaction { blockHash, blockHeight, blockTimestamp, err, gasSpent, id, tx { callData { contractId, data, fnName }, gasLimit, gasPrice, id, isDeploy, memo, txType } } fragment BlockInfo on Block { header { hash, gasLimit, height, prevBlockHash, seed, stateHash, timestamp, version }, fees, gasSpent, reward, transactions {...TransactionInfo} } query($id: String!) { block(hash: $id) {...BlockInfo} }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -86,7 +86,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[1][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[1][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($height: Float!) { block(height: $height) { header { hash } } }\\n ","topic":"gql"}",
"body": "query($height: Float!) { block(height: $height) { header { hash } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down Expand Up @@ -130,7 +130,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($height: Float!) { block(height: $height) { header { hash } } }\\n ","topic":"gql"}",
"body": "query($height: Float!) { block(height: $height) { header { hash } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -144,7 +144,7 @@ describe("duskAPI", () => {
// expect(fetchSpy.mock.calls[1][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[1][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($height: Float!) { block(height: $height) { header { hash } } }\\n ","topic":"gql"}",
"body": "query($height: Float!) { block(height: $height) { header { hash } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -166,7 +166,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"query($id: String!) { block(hash: $id) { header { json } } }","topic":"gql"}",
"body": "query($id: String!) { block(hash: $id) { header { json } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -189,7 +189,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n \\n\\nfragment TransactionInfo on SpentTransaction {\\n\\tblockHash,\\n\\tblockHeight,\\n\\tblockTimestamp,\\n err,\\n\\tgasSpent,\\n\\tid,\\n tx {\\n callData {\\n contractId,\\n data,\\n fnName\\n },\\n gasLimit,\\n gasPrice,\\n id,\\n isDeploy,\\n memo,\\n txType\\n }\\n}\\n\\nfragment BlockInfo on Block {\\n header {\\n hash,\\n gasLimit,\\n height,\\n prevBlockHash,\\n seed,\\n stateHash,\\n timestamp,\\n version\\n },\\n fees,\\n gasSpent,\\n reward,\\n transactions {...TransactionInfo}\\n}\\n\\n query($amount: Int!) { blocks(last: $amount) {...BlockInfo} }\\n ","topic":"gql"}",
"body": "fragment TransactionInfo on SpentTransaction { blockHash, blockHeight, blockTimestamp, err, gasSpent, id, tx { callData { contractId, data, fnName }, gasLimit, gasPrice, id, isDeploy, memo, txType } } fragment BlockInfo on Block { header { hash, gasLimit, height, prevBlockHash, seed, stateHash, timestamp, version }, fees, gasSpent, reward, transactions {...TransactionInfo} } query($amount: Int!) { blocks(last: $amount) {...BlockInfo} }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -214,7 +214,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n \\n\\nfragment TransactionInfo on SpentTransaction {\\n\\tblockHash,\\n\\tblockHeight,\\n\\tblockTimestamp,\\n err,\\n\\tgasSpent,\\n\\tid,\\n tx {\\n callData {\\n contractId,\\n data,\\n fnName\\n },\\n gasLimit,\\n gasPrice,\\n id,\\n isDeploy,\\n memo,\\n txType\\n }\\n}\\n\\nfragment BlockInfo on Block {\\n header {\\n hash,\\n gasLimit,\\n height,\\n prevBlockHash,\\n seed,\\n stateHash,\\n timestamp,\\n version\\n },\\n fees,\\n gasSpent,\\n reward,\\n transactions {...TransactionInfo}\\n}\\n\\n query($amount: Int!) {\\n blocks(last: $amount) {...BlockInfo},\\n transactions(last: $amount) {...TransactionInfo}\\n }\\n ","topic":"gql"}",
"body": "fragment TransactionInfo on SpentTransaction { blockHash, blockHeight, blockTimestamp, err, gasSpent, id, tx { callData { contractId, data, fnName }, gasLimit, gasPrice, id, isDeploy, memo, txType } } fragment BlockInfo on Block { header { hash, gasLimit, height, prevBlockHash, seed, stateHash, timestamp, version }, fees, gasSpent, reward, transactions {...TransactionInfo} } query($amount: Int!) { blocks(last: $amount) {...BlockInfo}, transactions(last: $amount) {...TransactionInfo} }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down Expand Up @@ -314,7 +314,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[1][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[1][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"query { block(height: -1) { header { height } } }","topic":"gql"}",
"body": "query { block(height: -1) { header { height } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -327,7 +327,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[2][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[2][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"query { blocks(last: 100) { transactions { err } } }","topic":"gql"}",
"body": "query { blocks(last: 100) { transactions { err } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -349,7 +349,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n \\nfragment TransactionInfo on SpentTransaction {\\n\\tblockHash,\\n\\tblockHeight,\\n\\tblockTimestamp,\\n err,\\n\\tgasSpent,\\n\\tid,\\n tx {\\n callData {\\n contractId,\\n data,\\n fnName\\n },\\n gasLimit,\\n gasPrice,\\n id,\\n isDeploy,\\n memo,\\n txType\\n }\\n}\\n\\n query($id: String!) { tx(hash: $id) {...TransactionInfo} }\\n ","topic":"gql"}",
"body": "fragment TransactionInfo on SpentTransaction { blockHash, blockHeight, blockTimestamp, err, gasSpent, id, tx { callData { contractId, data, fnName }, gasLimit, gasPrice, id, isDeploy, memo, txType } } query($id: String!) { tx(hash: $id) {...TransactionInfo} }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -373,7 +373,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"query($id: String!) { tx(hash: $id) { tx { json } } }","topic":"gql"}",
"body": "query($id: String!) { tx(hash: $id) { tx { json } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -396,7 +396,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n \\nfragment TransactionInfo on SpentTransaction {\\n\\tblockHash,\\n\\tblockHeight,\\n\\tblockTimestamp,\\n err,\\n\\tgasSpent,\\n\\tid,\\n tx {\\n callData {\\n contractId,\\n data,\\n fnName\\n },\\n gasLimit,\\n gasPrice,\\n id,\\n isDeploy,\\n memo,\\n txType\\n }\\n}\\n\\n query($amount: Int!) { transactions(last: $amount) {...TransactionInfo} }\\n ","topic":"gql"}",
"body": "fragment TransactionInfo on SpentTransaction { blockHash, blockHeight, blockTimestamp, err, gasSpent, id, tx { callData { contractId, data, fnName }, gasLimit, gasPrice, id, isDeploy, memo, txType } } query($amount: Int!) { transactions(last: $amount) {...TransactionInfo} }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down Expand Up @@ -498,7 +498,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($id: String!) {\\n block(hash: $id) { header { hash } },\\n tx(hash: $id) { id }\\n }\\n ","topic":"gql"}",
"body": "query($id: String!) { block(hash: $id) { header { hash } }, tx(hash: $id) { id } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand All @@ -512,7 +512,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[1][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[1][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($height: Float!) { block(height: $height) { header { hash } } }\\n ","topic":"gql"}",
"body": "query($height: Float!) { block(height: $height) { header { hash } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down Expand Up @@ -541,7 +541,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($id: String!) {\\n block(hash: $id) { header { hash } },\\n tx(hash: $id) { id }\\n }\\n ","topic":"gql"}",
"body": "query($id: String!) { block(hash: $id) { header { hash } }, tx(hash: $id) { id } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down Expand Up @@ -569,7 +569,7 @@ describe("duskAPI", () => {
expect(fetchSpy.mock.calls[0][0]).toStrictEqual(gqlExpectedURL);
expect(fetchSpy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"body": "{"data":"\\n query($height: Float!) { block(height: $height) { header { hash } } }\\n ","topic":"gql"}",
"body": "query($height: Float!) { block(height: $height) { header { hash } } }",
"headers": {
"Accept": "application/json",
"Accept-Charset": "utf-8",
Expand Down
7 changes: 2 additions & 5 deletions explorer/src/lib/services/duskAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,8 @@ const toHeadersVariables = unless(
* @param {{ query: string, variables?: Record<string, string | number> }} queryInfo
*/
const gqlGet = (queryInfo) =>
fetch(makeNodeUrl("/02/Chain"), {
body: JSON.stringify({
data: queryInfo.query,
topic: "gql",
}),
fetch(makeNodeUrl("/on/graphql/query"), {
body: queryInfo.query.replace(/\s+/g, " ").trim(),
headers: {
Accept: "application/json",
"Accept-Charset": "utf-8",
Expand Down
5 changes: 5 additions & 0 deletions rusk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added

- Add `/on/account:<address>/status` endpoint [#3422]

### Changed

- Change dependency declaration to not require strict equal [#3405]
Expand Down Expand Up @@ -296,6 +300,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add build system that generates keys for circuits and caches them.

<!-- Issues -->
[#3422]: https://github.com/dusk-network/rusk/issues/3422
[#3405]: https://github.com/dusk-network/rusk/issues/3405
[#3359]: https://github.com/dusk-network/rusk/issues/3359
[#3206]: https://github.com/dusk-network/rusk/issues/3206
Expand Down
25 changes: 24 additions & 1 deletion rusk/src/lib/http/rusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
use super::event::Event;
use super::*;

use dusk_bytes::Serializable;
use dusk_bytes::{DeserializableSlice, Serializable};
use dusk_core::abi::ContractId;
use dusk_core::signatures::bls::PublicKey as BlsPublicKey;
use dusk_core::stake::StakeFundOwner;
use node::vm::VMExecution;
use rusk_profile::CRS_17_HASH;
use serde::Serialize;
use serde_json::json;
use std::sync::{mpsc, Arc};
use std::thread;
use tokio::task;
Expand Down Expand Up @@ -44,6 +46,7 @@ impl HandleRequest for Rusk {
match request.uri.inner() {
("contracts", Some(_), _) => true,
("node", _, "provisioners") => true,
("account", Some(_), "status") => true,
("node", _, "crs") => true,
_ => false,
}
Expand All @@ -59,6 +62,8 @@ impl HandleRequest for Rusk {
self.handle_contract_query(contract_id, method, data, feeder)
}
("node", _, "provisioners") => self.get_provisioners(),

("account", Some(pk), "status") => self.get_account(pk),
("node", _, "crs") => self.get_crs(),
_ => Err(anyhow::anyhow!("Unsupported")),
}
Expand Down Expand Up @@ -151,6 +156,24 @@ impl Rusk {
Ok(ResponseData::new(serde_json::to_value(prov)?))
}

fn get_account(&self, pk: &str) -> anyhow::Result<ResponseData> {
let pk = bs58::decode(pk)
.into_vec()
.map_err(|_| anyhow::anyhow!("Invalid bs58 account"))?;
let pk = BlsPublicKey::from_slice(&pk)
.map_err(|_| anyhow::anyhow!("Invalid bls account"))?;
let account = self
.account(&pk)
.map(|account| {
json!({
"balance": account.balance,
"nonce": account.nonce,
})
})
.map_err(|e| anyhow::anyhow!("Cannot query the state {e:?}"))?;
Ok(ResponseData::new(account))
}

fn get_crs(&self) -> anyhow::Result<ResponseData> {
let crs = rusk_profile::get_common_reference_string()?;
Ok(ResponseData::new(crs).with_header("crs-hash", CRS_17_HASH))
Expand Down

0 comments on commit 01265e3

Please sign in to comment.