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

sdk - chain simulator requests refactor #1797

Merged
merged 2 commits into from
Oct 2, 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
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions sdk/core/src/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod gateway_account_esdt_roles;
mod gateway_account_esdt_tokens;
mod gateway_account_storage;
mod gateway_block;
mod gateway_chain_simulator_blocks;
mod gateway_chain_simulator_send_funds;
mod gateway_network_config;
mod gateway_network_economics;
mod gateway_network_status;
Expand All @@ -19,6 +21,8 @@ pub use gateway_account_esdt_roles::GetAccountEsdtRolesRequest;
pub use gateway_account_esdt_tokens::GetAccountEsdtTokensRequest;
pub use gateway_account_storage::GetAccountStorageRequest;
pub use gateway_block::GetHyperBlockRequest;
pub use gateway_chain_simulator_blocks::ChainSimulatorGenerateBlocksRequest;
pub use gateway_chain_simulator_send_funds::ChainSimulatorSendFundsRequest;
pub use gateway_network_config::NetworkConfigRequest;
pub use gateway_network_economics::NetworkEconimicsRequest;
pub use gateway_network_status::NetworkStatusRequest;
Expand Down Expand Up @@ -51,6 +55,13 @@ const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction/";
const WITH_RESULTS_QUERY_PARAM: &str = "?withResults=true";
const VM_VALUES_ENDPOINT: &str = "vm-values/query";

const SEND_USER_FUNDS_ENDPOINT: &str = "transaction/send-user-funds";
const GENERATE_BLOCKS_ENDPOINT: &str = "simulator/generate-blocks";
const GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT: &str =
"simulator/generate-blocks-until-transaction-processed";
const GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT: &str =
"simulator/generate-blocks-until-epoch-reached";

pub enum GatewayRequestType {
Get,
Post,
Expand Down
67 changes: 67 additions & 0 deletions sdk/core/src/gateway/gateway_chain_simulator_blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use anyhow::anyhow;
use serde::{Deserialize, Serialize};

use super::{
GatewayRequest, GatewayRequestType, GENERATE_BLOCKS_ENDPOINT,
GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT, GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT,
};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerateBlocksResponse {
pub data: serde_json::Value,
pub error: String,
pub code: String,
}

/// Generates blocks using the chain simulator API.
pub struct ChainSimulatorGenerateBlocksRequest {
pub query: String,
}

impl ChainSimulatorGenerateBlocksRequest {
pub fn num_blocks(num_blocks: u64) -> Self {
Self {
query: format!("{}/{}", GENERATE_BLOCKS_ENDPOINT, num_blocks),
}
}

pub fn until_epoch(epoch_number: u64) -> Self {
Self {
query: format!(
"{}/{}",
GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT, epoch_number
),
}
}

/// TODO: convert arg to H256
pub fn until_tx_processed(tx_hash: &str) -> Self {
Self {
query: format!(
"{}/{}",
GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT, tx_hash
),
}
}
}

impl GatewayRequest for ChainSimulatorGenerateBlocksRequest {
type Payload = ();
type DecodedJson = GenerateBlocksResponse;
type Result = String;

fn request_type(&self) -> GatewayRequestType {
GatewayRequestType::Post
}

fn get_endpoint(&self) -> String {
self.query.clone()
}

fn process_json(&self, decoded: Self::DecodedJson) -> anyhow::Result<Self::Result> {
match decoded.code.as_str() {
"successful" => Ok(decoded.code),
_ => Err(anyhow!("{}", decoded.error)),
}
}
}
47 changes: 47 additions & 0 deletions sdk/core/src/gateway/gateway_chain_simulator_send_funds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::collections::HashMap;

use anyhow::anyhow;

use super::{
gateway_chain_simulator_blocks::GenerateBlocksResponse, GatewayRequest, GatewayRequestType,
SEND_USER_FUNDS_ENDPOINT,
};

/// Generates blocks using the chain simulator API.
pub struct ChainSimulatorSendFundsRequest {
payload: HashMap<&'static str, String>,
}

impl ChainSimulatorSendFundsRequest {
/// TODO: convert to argument to Address
pub fn to_address(receiver: String) -> Self {
let mut payload = HashMap::new();
payload.insert("receiver", receiver);
Self { payload }
}
}

impl GatewayRequest for ChainSimulatorSendFundsRequest {
type Payload = HashMap<&'static str, String>;
type DecodedJson = GenerateBlocksResponse;
type Result = String;

fn request_type(&self) -> GatewayRequestType {
GatewayRequestType::Get
}

fn get_endpoint(&self) -> String {
SEND_USER_FUNDS_ENDPOINT.to_owned()
}

fn get_payload(&self) -> Option<&Self::Payload> {
Some(&self.payload)
}

fn process_json(&self, decoded: Self::DecodedJson) -> anyhow::Result<Self::Result> {
match decoded.code.as_str() {
"successful" => Ok(decoded.code),
_ => Err(anyhow!("{}", decoded.error)),
}
}
}
4 changes: 0 additions & 4 deletions sdk/http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ hex = "0.4.3"
itertools = "0.13.0"
log = "0.4.17"

# TEMP
serde = { version = "1.0.130", features = ["derive"] }
serde_json = { version = "1.0.68", features = ["preserve_order"] }

[dependencies.multiversx-sdk]
version = "=0.6.1"
path = "../core"
4 changes: 0 additions & 4 deletions sdk/http/src/gateway_http_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ impl GatewayHttpProxy {
}
}

pub(crate) fn get_endpoint(&self, endpoint: &str) -> String {
format!("{}/{}", self.proxy_uri, endpoint)
}

/// Performs a request to the gateway.
/// Can be either GET or POST, depending on the argument.
pub async fn http_request<G>(&self, request: G) -> anyhow::Result<G::Result>
Expand Down
104 changes: 21 additions & 83 deletions sdk/http/src/gateway_http_proxy/http_chain_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,111 +1,49 @@
use std::collections::HashMap;

use super::GatewayHttpProxy;
use anyhow::{anyhow, Error};
use serde::{Deserialize, Serialize};

const SEND_USER_FUNDS_ENDPOINT: &str = "transaction/send-user-funds";
const GENERATE_BLOCKS_ENDPOINT: &str = "simulator/generate-blocks";
const GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT: &str =
"simulator/generate-blocks-until-transaction-processed";
const GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT: &str =
"simulator/generate-blocks-until-epoch-reached";

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerateBlocksResponse {
pub data: serde_json::Value,
pub error: String,
pub code: String,
}
use anyhow::Error;
use multiversx_sdk::gateway::{
ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, GatewayAsyncService,
};

impl GatewayHttpProxy {
pub async fn send_user_funds(&self, receiver: &String) -> Result<String, Error> {
pub async fn send_user_funds(&self, receiver: &str) -> Result<String, Error> {
if !self.chain_simulator {
return Ok(String::from("no-simulator"));
}

let mut r = HashMap::new();
r.insert("receiver", receiver);
let endpoint_funds = self.get_endpoint(SEND_USER_FUNDS_ENDPOINT);
let resp = self
.client
.post(endpoint_funds)
.json(&r)
.send()
.await?
.json::<GenerateBlocksResponse>()
.await?;

match resp.code.as_str() {
"successful" => Ok(resp.code),
_ => Err(anyhow!("{}", resp.error)),
}
self.request(ChainSimulatorSendFundsRequest::to_address(
receiver.to_owned(),
))
.await
}

pub async fn generate_blocks(&self, number_blocks: u64) -> Result<String, Error> {
pub async fn generate_blocks(&self, num_blocks: u64) -> Result<String, Error> {
if !self.chain_simulator {
return Ok(String::from("no-simulator"));
}

let uri_gen_blocks: String = format!("{}/{}", GENERATE_BLOCKS_ENDPOINT, number_blocks);
let endpoint_blocks = self.get_endpoint(&uri_gen_blocks);
let resp = self
.client
.post(endpoint_blocks)
.send()
.await?
.json::<GenerateBlocksResponse>()
.await?;

match resp.code.as_str() {
"successful" => Ok(resp.code),
_ => Err(anyhow!("{}", resp.error)),
}
self.request(ChainSimulatorGenerateBlocksRequest::num_blocks(num_blocks))
.await
}

pub async fn generate_blocks_until_epoch(&self, epoch_number: u64) -> Result<String, Error> {
if !self.chain_simulator {
return Ok(String::from("no-simulator"));
}

let uri_gen_blocks_until_reached_epoch: String = format!(
"{}/{}",
GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT, epoch_number
);
let endpoint_blocks = self.get_endpoint(&uri_gen_blocks_until_reached_epoch);
let resp = self
.client
.post(endpoint_blocks)
.send()
.await?
.json::<GenerateBlocksResponse>()
.await?;

match resp.code.as_str() {
"successful" => Ok(resp.code),
_ => Err(anyhow!("{}", resp.error)),
}
self.request(ChainSimulatorGenerateBlocksRequest::until_epoch(
epoch_number,
))
.await
}

pub async fn generate_blocks_until_tx_processed(&self, tx: &String) -> Result<String, Error> {
pub async fn generate_blocks_until_tx_processed(&self, tx_hash: &str) -> Result<String, Error> {
if !self.chain_simulator {
return Ok(String::from("no-simulator"));
}

let url_gen_blocks_until_tx_processed: String =
format!("{}/{}", GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT, tx);
let endpoint_blocks = self.get_endpoint(&url_gen_blocks_until_tx_processed);
let resp = self
.client
.post(endpoint_blocks)
.send()
.await?
.json::<GenerateBlocksResponse>()
.await?;

match resp.code.as_str() {
"successful" => Ok(resp.code),
_ => Err(anyhow!("{}", resp.error)),
}
self.request(ChainSimulatorGenerateBlocksRequest::until_tx_processed(
tx_hash,
))
.await
}
}
Loading