Skip to content

Commit

Permalink
Merge pull request #12 from functionland/feature/im_online
Browse files Browse the repository at this point in the history
Feature/im online
  • Loading branch information
ehsan6sha authored Mar 10, 2024
2 parents dad2b77 + 13acf6d commit a1d3e66
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 4 deletions.
8 changes: 6 additions & 2 deletions crates/sugarfunge-api-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#[subxt::subxt(
runtime_metadata_path = "sugarfunge_metadata.scale",
derive_for_type(path = "frame_support::traits::tokens::misc::BalanceStatus", derive = "serde::Serialize"),
derive_for_type(
path = "frame_support::traits::tokens::misc::BalanceStatus",
derive = "serde::Serialize"
),
derive_for_type(path = "pallet_balances::pallet::Event", derive = "serde::Serialize"),
derive_for_type(path = "sugarfunge_asset::pallet::Event", derive = "serde::Serialize"),
derive_for_type(path = "sugarfunge_bag::pallet::Event", derive = "serde::Serialize"),
derive_for_type(path = "sugarfunge_bag::pallet::Event", derive = "serde::Serialize")
)]
pub mod sugarfunge {}
pub mod account;
Expand All @@ -14,6 +17,7 @@ pub mod challenge;
pub mod contract;
pub mod fula;
pub mod market;
pub mod online;
pub mod pool;
pub mod primitives;
pub mod validator;
16 changes: 16 additions & 0 deletions crates/sugarfunge-api-types/src/online.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct GetAuthoredBlocks {
pub validators: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct GetHeartbeats {
pub validators: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct HeartbeatTime {
pub time: Option<u32>,
}
2 changes: 2 additions & 0 deletions crates/sugarfunge-api-types/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub struct CreatePoolOutput {
pub struct LeavePoolInput {
pub seed: Seed,
pub pool_id: PoolId,
pub target_account: Option<Account>, // Optional target account to be removed
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -52,6 +53,7 @@ pub struct JoinPoolOutput {
pub struct CancelJoinPoolInput {
pub seed: Seed,
pub pool_id: PoolId,
pub target_account: Option<Account>, // Optional target account to be removed
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down
17 changes: 17 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mod config;
mod contract;
mod fula;
mod market;
mod online;
mod pool;
mod state;
mod subscription;
Expand Down Expand Up @@ -102,6 +103,10 @@ async fn main() -> std::io::Result<()> {
"validator/add_validator",
web::post().to(validator::add_validator),
)
.route(
"validator/activate",
web::post().to(validator::activate_validator),
)
.route("validator/set_keys", web::post().to(validator::set_keys))
.route(
"validator/remove_validator",
Expand Down Expand Up @@ -236,6 +241,18 @@ async fn main() -> std::io::Result<()> {
"fula/mumbai/convert_tokens",
web::post().to(contract::mumbai_convert_to_fula_endpoint),
)
.route(
"fula/online/get_heartbeats",
web::post().to(online::get_heartbeats),
)
.route(
"fula/online/get_authored_blocks",
web::post().to(online::get_authored_blocks),
)
.route(
"fula/online/get_heartbeat_time",
web::post().to(online::get_heartbeat_time),
)
})
.bind((args.listen.host_str().unwrap(), args.listen.port().unwrap()))?
.run()
Expand Down
82 changes: 82 additions & 0 deletions src/online.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::state::*;
use crate::util::*;
use actix_web::{error, web, HttpResponse};
use futures::stream::StreamExt;
use sugarfunge_api_types::online::*;
use sugarfunge_api_types::sugarfunge;

pub async fn get_authored_blocks(data: web::Data<AppState>) -> error::Result<HttpResponse> {
let api = &data.api;
let result_array = Vec::new();

let query_key = sugarfunge::storage()
.im_online()
.authored_blocks_iter()
.to_root_bytes();

let storage = api.storage().at_latest().await.map_err(map_subxt_err)?;

let keys_stream = storage
.fetch_raw_keys(query_key)
.await
.map_err(map_subxt_err)?;

let keys: Vec<Vec<u8>> = keys_stream
.collect::<Vec<_>>() // Collect into a Vec<Result<Vec<u8>, Error>>
.await // Await the collection process
.into_iter() // Convert into an iterator
.filter_map(Result::ok) // Filter out Ok values, ignore errors
.collect(); // Collect into a Vec<Vec<u8>>

println!("Obtained keys:");
for key in keys.iter() {
println!("Key: len: {} 0x{}", key.len(), hex::encode(&key));
}
Ok(HttpResponse::Ok().json(GetAuthoredBlocks {
validators: result_array,
}))
}

pub async fn get_heartbeats(data: web::Data<AppState>) -> error::Result<HttpResponse> {
let api = &data.api;
let result_array = Vec::new();

let query_key = sugarfunge::storage()
.im_online()
.received_heartbeats_iter()
.to_root_bytes();

let storage = api.storage().at_latest().await.map_err(map_subxt_err)?;

let keys_stream = storage
.fetch_raw_keys(query_key)
.await
.map_err(map_subxt_err)?;

let keys: Vec<Vec<u8>> = keys_stream
.collect::<Vec<_>>() // Collect into a Vec<Result<Vec<u8>, Error>>
.await // Await the collection process
.into_iter() // Convert into an iterator
.filter_map(Result::ok) // Filter out Ok values, ignore errors
.collect(); // Collect into a Vec<Vec<u8>>

// println!("Obtained keys:");
for key in keys.iter() {
println!("Key: len: {} 0x{}", key.len(), hex::encode(&key));
}
Ok(HttpResponse::Ok().json(GetHeartbeats {
validators: result_array,
}))
}

pub async fn get_heartbeat_time(data: web::Data<AppState>) -> error::Result<HttpResponse> {
let api = &data.api;

let query_key = sugarfunge::storage().im_online().heartbeat_after();

let storage = api.storage().at_latest().await.map_err(map_subxt_err)?;

let keys_stream = storage.fetch(&query_key).await.map_err(map_subxt_err)?;

Ok(HttpResponse::Ok().json(HeartbeatTime { time: keys_stream }))
}
16 changes: 14 additions & 2 deletions src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,15 @@ pub async fn leave_pool(
let pair = get_pair_from_seed(&req.seed)?;
let signer = PairSigner::new(pair);

let mut target_account: Option<AccountId32> = None::<AccountId32>;
if let Some(value) = req.target_account.clone() {
target_account = Some(AccountId32::try_from(&value).map_err(map_account_err)?);
}
let api = &data.api;

let call = sugarfunge::tx().pool().leave_pool(req.pool_id.into());
let call = sugarfunge::tx()
.pool()
.leave_pool(req.pool_id.into(), target_account);
let set_balance = get_balance(&req.seed).await;
let result = api
.tx()
Expand Down Expand Up @@ -154,9 +160,15 @@ pub async fn cancel_join_pool(
let pair = get_pair_from_seed(&req.seed)?;
let signer = PairSigner::new(pair);

let mut target_account: Option<AccountId32> = None::<AccountId32>;
if let Some(value) = req.target_account.clone() {
target_account = Some(AccountId32::try_from(&value).map_err(map_account_err)?);
}
let api = &data.api;

let call = sugarfunge::tx().pool().cancel_join(req.pool_id.into());
let call = sugarfunge::tx()
.pool()
.cancel_join(req.pool_id.into(), target_account);
let set_balance = get_balance(&req.seed).await;
let result = api
.tx()
Expand Down
38 changes: 38 additions & 0 deletions src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,44 @@ pub async fn add_validator(
}
}

pub async fn activate_validator(
data: web::Data<AppState>,
req: web::Json<AddValidatorInput>,
) -> error::Result<HttpResponse> {
let pair = get_pair_from_seed(&req.seed)?;
let signer = PairSigner::new(pair);
let validator_public =
sp_core::sr25519::Public::from_str(req.validator_id.as_str()).map_err(map_account_err)?;
let validator_bytes: [u8; 32] = validator_public.0; // Convert Public key to a byte array
let validator_id = subxt::utils::AccountId32::from(validator_bytes); // Create AccountId32 from the byte array
let api = &data.api;

let call = sugarfunge::tx().validator_set().add_validator_again(validator_id);

let result = api
.tx()
.sign_and_submit_then_watch(&call, &signer, Default::default())
.await
.map_err(map_subxt_err)?
.wait_for_finalized_success()
.await
.map_err(map_sf_err)?;

let result = result
.find_first::<sugarfunge::validator_set::events::ValidatorAdditionInitiated>()
.map_err(map_subxt_err)?;

match result {
Some(event) => Ok(HttpResponse::Ok().json(AddValidatorOutput {
validator_id: ValidatorId::from(event.0.to_string()),
})),
None => Ok(HttpResponse::BadRequest().json(RequestError {
message: json!("Failed to find sugarfunge::validator::events::ActivateValidator"),
description: String::new(),
})),
}
}

pub async fn remove_validator(
data: web::Data<AppState>,
req: web::Json<RemoveValidatorInput>,
Expand Down

0 comments on commit a1d3e66

Please sign in to comment.