Skip to content

Commit

Permalink
fixup! refactor!: rollup-http-server based on libcmt
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmikhalevich committed Mar 20, 2024
1 parent 250a383 commit e44fee7
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 4 deletions.
39 changes: 37 additions & 2 deletions rollup-http/rollup-http-server/src/http_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use tokio::sync::Notify;
use crate::config::Config;
use crate::rollup::{self, RollupFd};
use crate::rollup::{
AdvanceRequest, Exception, InspectRequest, Notice, Report, RollupRequest, Voucher,
AdvanceRequest, Exception, InspectRequest, Notice, Report, RollupRequest, Voucher, GioRequest,
};

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -142,7 +142,7 @@ async fn report(report: Json<Report>, data: Data<Mutex<Context>>) -> HttpRespons
Err(e) => {
log::error!("unable to insert report, error details: '{}'", e);
HttpResponse::BadRequest()
.body(format!("unable to insert notice, error details: '{}'", e))
.body(format!("unable to insert report, error details: '{}'", e))
}
};
}
Expand Down Expand Up @@ -236,6 +236,41 @@ async fn finish(finish: Json<FinishRequest>, data: Data<Mutex<Context>>) -> Http
.json(http_rollup_request)
}

/// Process general input/output request from DApp, write payload to the rollup device
/// and respond to DApp with an output
#[actix_web::post("/gio")]
async fn gio(gio: Json<GioRequest>, data: Data<Mutex<Context>>) -> HttpResponse {
log::debug!("received general input/output request");
let context = data.lock().await;
// write request data to the linux rollup device
return match rollup::rollup_write_gio_payload(&*context.rollup_fd.lock().await, &gio.0) {
Ok(_) => {
log::debug!("gio request successfully inserted {:#?}", gio);
HttpResponse::Accepted().body("")
}
Err(e) => {
log::error!("unable to insert gio request, error details: '{}'", e);
HttpResponse::BadRequest()
.body(format!("unable to insert gio request, error details: '{}'", e))
}
};

// read response data from the linux rollup device and return it to the dapp
return match rollup::rollup_read_gio_response(&*context.rollup_fd.lock().await) {
Ok(gio_response) => {
log::debug!("got gio response successfully {:#?}", gio);
HttpResponse::Ok()
.append_header((hyper::header::CONTENT_TYPE, "application/json"))
.json(gio_response)
}
Err(e) => {
log::error!("unable to get gio response, error details: '{}'", e);
HttpResponse::BadRequest()
.body(format!("unable to get gio response, error details: '{}'", e))
}
}
}

#[derive(Debug, Clone, Deserialize)]
struct FinishRequest {
status: String,
Expand Down
98 changes: 96 additions & 2 deletions rollup-http/rollup-http-server/src/rollup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ pub enum RollupResponse {
Finish(bool),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GioRequest {
pub domain: u32,
pub payload: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GioResponse {
pub payload: String,
}

pub fn rollup_finish_request(
fd: &RollupFd,
finish: &mut RollupFinish,
Expand Down Expand Up @@ -337,7 +348,6 @@ pub fn rollup_write_notice(
Ok(notice_index as u64)
}


pub fn rollup_write_voucher(
fd: &RollupFd,
voucher: &mut Voucher,
Expand Down Expand Up @@ -437,6 +447,83 @@ pub fn rollup_write_report(fd: &RollupFd, report: &Report) -> Result<(), Box<dyn
Ok(())
}

pub fn rollup_write_gio_payload(fd: &RollupFd, gio_request: &GioRequest) -> Result<(), Box<dyn std::error::Error>> {
print_gio_request(gio_request);

let binary_payload = match hex::decode(&gio_request.payload[2..]) {
Ok(payload) => payload,
Err(_err) => {
return Err(Box::new(RollupError::new(&format!(
"Error decoding report payload, payload must be in Ethereum hex binary format"
))));
}
};

let mut buffer: Vec<u8> = Vec::with_capacity(binary_payload.len());
let data = buffer.as_mut_ptr() as *mut c_void;
let length = binary_payload.len();

let res = unsafe {
cmt_gio_request(
fd.0,
gio_request.domain,
binary_payload.len() as u32,
binary_payload.as_ptr() as *const c_void,
length as u32,
data as *mut c_void,
);
};
if res != 0 {
return Err(Box::new(RollupError::new(&format!(
"IOCTL_ROLLUP_GIO_REQUEST returned error {}",
res
))));
} else {
log::debug!("gio request successfully written!");
}

Ok(())
}

pub fn rollup_read_gio_response(
fd: &RollupFd,
) -> Result<GioResponse, Box<dyn std::error::Error>> {

let mut gio_response = Box::new(cmt_gio_response_t {
payload_length: 0,
payload: std::ptr::null::<::std::os::raw::c_uchar>() as *mut c_void,
});

let res = unsafe {
cmt_gio_read_response(fd.0, gio_response.as_mut())
};

if res != 0 {
return Err(Box::new(RollupError::new(&format!(
"IOCTL_ROLLUP_READ_GIO_RESPONSE returned error {}",
res
))));
}

if gio_response.payload_length == 0 {
log::info!("read zero size payload from gio response");
}

let mut payload: Vec<u8> = Vec::with_capacity(gio_response.payload_length as usize);
if advance_request.payload_length > 0 {
unsafe {
std::ptr::copy(gio_response.payload, payload.as_mut_ptr() as *mut c_void, gio_response.payload_length as usize);
payload.set_len(gio_response.payload_length as usize);
}
}

let result = GioResponse {
payload: "0x".to_string() + &hex::encode(&payload),
};

Ok(result)
}

pub fn rollup_throw_exception(
fd: &RollupFd,
exception: &Exception,
Expand Down Expand Up @@ -580,7 +667,6 @@ pub fn print_notice(notice: &Notice) {
);
}


pub fn print_voucher(voucher: &Voucher) {
let mut voucher_request_printout = String::new();
voucher_request_printout.push_str("voucher: {{ destination: ");
Expand All @@ -601,6 +687,14 @@ pub fn print_report(report: &Report) {
);
}

pub fn print_gio_request(gio_request: &GioRequest) {
log::debug!(
"gio_request: {{ domain: {} payload: {}}}",
gio_request.domain,
gio_request.payload
);
}

pub fn print_exception(exception: &Exception) {
log::debug!(
"exception: {{ length: {} payload: {}}}",
Expand Down

0 comments on commit e44fee7

Please sign in to comment.