use std::collections::BTreeMap;
use async_graphql::{scalar, Request, Response, SimpleObject};
use linera_sdk_derive::GraphQLMutationRootInCrate;
use serde::{Deserialize, Serialize};
use crate::linera_base_types::{
AccountOwner, ApplicationId, ChainId, ContractAbi, DataBlobHash, MessagePolicy, ServiceAbi,
};
pub struct ControllerAbi;
impl ContractAbi for ControllerAbi {
type Operation = Operation;
type Response = ();
}
impl ServiceAbi for ControllerAbi {
type Query = Request;
type QueryResponse = Response;
}
pub type ManagedServiceId = DataBlobHash;
#[derive(Debug, Deserialize, Serialize, GraphQLMutationRootInCrate)]
pub enum Operation {
ExecuteWorkerCommand {
owner: AccountOwner,
command: WorkerCommand,
},
ExecuteControllerCommand {
admin: AccountOwner,
command: ControllerCommand,
},
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum WorkerCommand {
RegisterWorker { capabilities: Vec<String> },
DeregisterWorker,
}
scalar!(WorkerCommand);
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ControllerCommand {
SetAdmins { admins: Option<Vec<AccountOwner>> },
RemoveWorker { worker_id: ChainId },
UpdateService {
service_id: ManagedServiceId,
workers: Vec<ChainId>,
},
RemoveService { service_id: ManagedServiceId },
UpdateAllServices {
services: Vec<(ManagedServiceId, Vec<ChainId>)>,
},
UpdateChain {
chain_id: ChainId,
workers: Vec<ChainId>,
},
RemoveChain { chain_id: ChainId },
UpdateAllChains {
chains: Vec<(ChainId, Vec<ChainId>)>,
},
}
scalar!(ControllerCommand);
#[derive(Clone, Debug, Serialize, Deserialize, SimpleObject)]
pub struct Worker {
pub owner: AccountOwner,
pub capabilities: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ManagedService {
pub application_id: ApplicationId,
pub name: String,
pub chain_id: ChainId,
pub requirements: Vec<String>,
}
scalar!(ManagedService);
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LocalWorkerState {
pub local_worker: Option<Worker>,
pub local_services: Vec<ManagedService>,
pub local_chains: Vec<ChainId>,
pub local_message_policy: BTreeMap<ChainId, MessagePolicy>,
}
scalar!(LocalWorkerState);
#[derive(Clone, Debug, Deserialize, Serialize, GraphQLMutationRootInCrate)]
pub enum Message {
ExecuteWorkerCommand {
owner: AccountOwner,
command: WorkerCommand,
},
ExecuteControllerCommand {
admin: AccountOwner,
command: ControllerCommand,
},
Reset,
Start {
service_id: ManagedServiceId,
},
Stop {
service_id: ManagedServiceId,
},
FollowChain {
chain_id: ChainId,
},
ForgetChain {
chain_id: ChainId,
},
}
#[cfg(not(target_arch = "wasm32"))]
pub mod formats {
use serde_reflection::{Samples, Tracer, TracerConfig};
use super::{
ControllerAbi, ControllerCommand, ManagedServiceId, Message, Operation, Worker,
WorkerCommand,
};
use crate::{
formats::{BcsApplication, Formats},
linera_base_types::AccountOwner,
};
pub struct ControllerApplication;
impl BcsApplication for ControllerApplication {
type Abi = ControllerAbi;
fn formats() -> serde_reflection::Result<Formats> {
let mut tracer = Tracer::new(
TracerConfig::default()
.record_samples_for_newtype_structs(true)
.record_samples_for_tuple_structs(true),
);
let samples = Samples::new();
let (operation, _) = tracer.trace_type::<Operation>(&samples)?;
let (response, _) = tracer.trace_type::<()>(&samples)?;
let (message, _) = tracer.trace_type::<Message>(&samples)?;
let (event_value, _) = tracer.trace_type::<()>(&samples)?;
tracer.trace_type::<WorkerCommand>(&samples)?;
tracer.trace_type::<ControllerCommand>(&samples)?;
tracer.trace_type::<Worker>(&samples)?;
tracer.trace_type::<ManagedServiceId>(&samples)?;
tracer.trace_type::<AccountOwner>(&samples)?;
let registry = tracer.registry()?;
Ok(Formats {
registry,
operation,
response,
message,
event_value,
})
}
}
}