From e44fee72644b18e637dd502736a5c2d9936a969c Mon Sep 17 00:00:00 2001 From: Alex Mikhalevich <2990126+alexmikhalevich@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:14:24 +0100 Subject: [PATCH] fixup! refactor!: rollup-http-server based on libcmt --- .../rollup-http-server/src/http_service.rs | 39 +++++++- .../rollup-http-server/src/rollup/mod.rs | 98 ++++++++++++++++++- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/rollup-http/rollup-http-server/src/http_service.rs b/rollup-http/rollup-http-server/src/http_service.rs index ee30a6ad..5adaa50b 100644 --- a/rollup-http/rollup-http-server/src/http_service.rs +++ b/rollup-http/rollup-http-server/src/http_service.rs @@ -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)] @@ -142,7 +142,7 @@ async fn report(report: Json, data: Data>) -> 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)) } }; } @@ -236,6 +236,41 @@ async fn finish(finish: Json, data: Data>) -> 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, data: Data>) -> 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, diff --git a/rollup-http/rollup-http-server/src/rollup/mod.rs b/rollup-http/rollup-http-server/src/rollup/mod.rs index 3040480c..f46245a2 100644 --- a/rollup-http/rollup-http-server/src/rollup/mod.rs +++ b/rollup-http/rollup-http-server/src/rollup/mod.rs @@ -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, @@ -337,7 +348,6 @@ pub fn rollup_write_notice( Ok(notice_index as u64) } - pub fn rollup_write_voucher( fd: &RollupFd, voucher: &mut Voucher, @@ -437,6 +447,83 @@ pub fn rollup_write_report(fd: &RollupFd, report: &Report) -> Result<(), Box Result<(), Box> { + 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 = 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> { + + 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 = 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, @@ -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: "); @@ -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: {}}}",