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

GIO endpoint #42

Merged
merged 2 commits into from
Apr 19, 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
48 changes: 37 additions & 11 deletions rollup-http/rollup-http-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
// limitations under the License.
//

use crate::rollup::{AdvanceRequest, Exception, IndexResponse, InspectRequest, Notice, Report, RollupRequest, RollupResponse, Voucher};
use crate::rollup::{
AdvanceRequest, Exception, GIORequest, IndexResponse, InspectRequest, Notice, Report,
RollupRequest, RollupResponse, Voucher,
};
use hyper::Response;
use serde::{Deserialize, Serialize};
use std::io::ErrorKind;

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "request_type")]
enum RollupHttpRequest {
#[serde(rename = "advance_state")]
Advance {
data: AdvanceRequest,
},
Advance { data: AdvanceRequest },
#[serde(rename = "inspect_state")]
Inspect {
data: InspectRequest,
},
Inspect { data: InspectRequest },
}

pub async fn send_voucher(rollup_http_server_addr: &str, voucher: Voucher) {
Expand Down Expand Up @@ -98,11 +98,37 @@ pub async fn send_report(rollup_http_server_addr: &str, report: Report) {
}
}

pub async fn send_gio_request(
rollup_http_server_addr: &str,
gio_request: GIORequest,
) -> Response<hyper::Body> {
log::debug!("sending gio request to {}", rollup_http_server_addr);
let client = hyper::Client::new();
let req = hyper::Request::builder()
.method(hyper::Method::POST)
.header(hyper::header::CONTENT_TYPE, "application/json")
.uri(rollup_http_server_addr.to_string() + "/gio")
.body(hyper::Body::from(
serde_json::to_string(&gio_request).unwrap(),
))
.expect("gio request");
match client.request(req).await {
Ok(res) => {
log::info!("got gio response: {:?}", res);
res
}
Err(e) => {
log::error!("failed to send gio request to rollup http server: {}", e);
Response::builder()
.status(500)
.body(hyper::Body::empty())
.unwrap()
}
}
}

pub async fn throw_exception(rollup_http_server_addr: &str, exception: Exception) {
log::debug!(
"throwing exception request to {}",
rollup_http_server_addr
);
log::debug!("throwing exception request to {}", rollup_http_server_addr);
let client = hyper::Client::new();
let req = hyper::Request::builder()
.method(hyper::Method::POST)
Expand Down
2 changes: 1 addition & 1 deletion rollup-http/rollup-http-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod client;
pub mod rollup;
pub mod rollup;
12 changes: 12 additions & 0 deletions rollup-http/rollup-http-client/src/rollup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ pub struct IndexResponse {
index: u64,
}

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

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GIOResponse {
pub response_code: u16,
pub response: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Exception {
pub payload: String,
Expand Down
1 change: 1 addition & 0 deletions rollup-http/rollup-http-server/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn main() {

// link the libcmt shared library
println!("cargo:rustc-link-search=native={}", lib_dir);
println!("cargo:rerun-if-changed={}/libcmt.a", lib_dir);
mpolitzer marked this conversation as resolved.
Show resolved Hide resolved
println!("cargo:rustc-link-lib=static=cmt");

let bindings = bindgen::Builder::default()
Expand Down
27 changes: 25 additions & 2 deletions rollup-http/rollup-http-server/src/http_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ use actix_web::{middleware::Logger, web::Data, App, HttpResponse, HttpServer};
use actix_web_validator::Json;
use async_mutex::Mutex;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::sync::Notify;

use crate::config::Config;
use crate::rollup::{self, RollupFd};
use crate::rollup::{self, GIORequest, RollupFd};
use crate::rollup::{
AdvanceRequest, Exception, InspectRequest, Notice, Report, RollupRequest, FinishRequest, Voucher,
AdvanceRequest, Exception, FinishRequest, InspectRequest, Notice, Report, RollupRequest,
Voucher,
};

#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -52,6 +54,7 @@ pub fn create_server(
.service(voucher)
.service(notice)
.service(report)
.service(gio)
.service(exception)
.service(finish)
})
Expand Down Expand Up @@ -148,6 +151,26 @@ async fn report(report: Json<Report>, data: Data<Mutex<Context>>) -> HttpRespons
};
}

/// Process gio request and return the result
#[actix_web::post("/gio")]
async fn gio(request: Json<GIORequest>, data: Data<Mutex<Context>>) -> HttpResponse {
log::debug!("received gio request {:#?}", request);
let context = data.lock().await;
return match rollup::gio_request(&*context.rollup_fd.lock().await, &request.0) {
Ok(result) => {
log::debug!("gio successfully processed, response: {:#?}", result);
HttpResponse::Accepted().body(json!(result).to_string())
}
Err(e) => {
log::error!("unable to process gio request, error details: '{}'", e);
HttpResponse::BadRequest().body(format!(
"unable to process gio request, error details: '{}'",
e
))
}
};
}

/// The DApp should call this method when it cannot proceed with the request processing after an exception happens.
/// This method should be the last method ever called by the DApp backend, and it should not expect the call to return.
/// The Rollup HTTP Server will pass the exception info to the Cartesi Server Manager.
Expand Down
Empty file.
126 changes: 107 additions & 19 deletions rollup-http/rollup-http-server/src/rollup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

use std::io::ErrorKind;

use lazy_static::lazy_static;
use libc::c_void;
use regex::Regex;
use serde::{Deserialize, Serialize};
use validator::Validate;
use regex::Regex;
use lazy_static::lazy_static;

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

Expand Down Expand Up @@ -114,6 +114,19 @@ impl From<&mut RollupFinish> for cmt_rollup_finish_t {
}
}

#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct GIORequest {
#[validate(range(min = 0x10))] // avoid overlapping with our HTIF_YIELD_MANUAL_REASON_*
pub domain: u16,
pub payload: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GIOResponse {
pub response_code: u16,
pub response: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdvanceMetadata {
pub msg_sender: String,
Expand Down Expand Up @@ -168,7 +181,7 @@ pub struct FinishRequest {

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InspectReport {
pub reports: Vec<Report>
pub reports: Vec<Report>,
}

#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
Expand Down Expand Up @@ -226,7 +239,6 @@ pub fn rollup_finish_request(
pub fn rollup_read_advance_state_request(
fd: &RollupFd,
) -> Result<AdvanceRequest, Box<dyn std::error::Error>> {

let mut advance_request = Box::new(cmt_rollup_advance_t {
chain_id: 0,
msg_sender: Default::default(),
Expand All @@ -238,9 +250,7 @@ pub fn rollup_read_advance_state_request(
payload: std::ptr::null::<::std::os::raw::c_uchar>() as *mut c_void,
});

let res = unsafe {
cmt_rollup_read_advance_state(fd.0, advance_request.as_mut())
};
let res = unsafe { cmt_rollup_read_advance_state(fd.0, advance_request.as_mut()) };

if res != 0 {
return Err(Box::new(RollupError::new(&format!(
Expand All @@ -256,7 +266,11 @@ pub fn rollup_read_advance_state_request(
let mut payload: Vec<u8> = Vec::with_capacity(advance_request.payload_length as usize);
if advance_request.payload_length > 0 {
unsafe {
std::ptr::copy(advance_request.payload, payload.as_mut_ptr() as *mut c_void, advance_request.payload_length as usize);
std::ptr::copy(
advance_request.payload,
payload.as_mut_ptr() as *mut c_void,
advance_request.payload_length as usize,
);
payload.set_len(advance_request.payload_length as usize);
}
}
Expand All @@ -269,19 +283,15 @@ pub fn rollup_read_advance_state_request(
Ok(result)
}


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

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

let res = unsafe {
cmt_rollup_read_inspect_state(fd.0, inspect_request.as_mut())
};
let res = unsafe { cmt_rollup_read_inspect_state(fd.0, inspect_request.as_mut()) };

if res != 0 {
return Err(Box::new(RollupError::new(&format!(
Expand All @@ -294,11 +304,18 @@ pub fn rollup_read_inspect_state_request(
log::info!("read zero size payload from inspect state request");
}

println!("inspect_request.payload_length: {}", inspect_request.payload_length);
println!(
"inspect_request.payload_length: {}",
inspect_request.payload_length
);
let mut payload: Vec<u8> = Vec::with_capacity(inspect_request.payload_length as usize);
if inspect_request.payload_length > 0 {
unsafe {
std::ptr::copy(inspect_request.payload, payload.as_mut_ptr() as *mut c_void, inspect_request.payload_length as usize);
std::ptr::copy(
inspect_request.payload,
payload.as_mut_ptr() as *mut c_void,
inspect_request.payload_length as usize,
);
payload.set_len(inspect_request.payload_length as usize);
}
}
Expand Down Expand Up @@ -336,7 +353,12 @@ pub fn rollup_write_notice(
binary_payload.len(),
);

cmt_rollup_emit_notice(fd.0, length as u32, buffer.as_mut_ptr() as *mut c_void, &mut notice_index)
cmt_rollup_emit_notice(
fd.0,
length as u32,
buffer.as_mut_ptr() as *mut c_void,
&mut notice_index,
)
};

if res != 0 {
Expand All @@ -351,7 +373,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 @@ -429,7 +450,10 @@ pub fn rollup_write_voucher(
Ok(voucher_index as u64)
}

pub fn rollup_write_report(fd: &RollupFd, report: &Report) -> Result<(), Box<dyn std::error::Error>> {
pub fn rollup_write_report(
fd: &RollupFd,
report: &Report,
) -> Result<(), Box<dyn std::error::Error>> {
print_report(report);

let binary_payload = match hex::decode(&report.payload[2..]) {
Expand Down Expand Up @@ -467,6 +491,71 @@ pub fn rollup_write_report(fd: &RollupFd, report: &Report) -> Result<(), Box<dyn
Ok(())
}

pub fn gio_request(
fd: &RollupFd,
gio: &GIORequest,
) -> Result<GIOResponse, Box<dyn std::error::Error>> {
println!("going to do gio_request");
let binary_payload = match hex::decode(&gio.payload[2..]) {
Ok(payload) => payload,
Err(_err) => {
return Err(Box::new(RollupError::new(&format!(
"Error decoding gio request 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;
unsafe {
std::ptr::copy(
binary_payload.as_ptr(),
buffer.as_mut_ptr(),
binary_payload.len(),
);
};

let mut gio_request = Box::new(cmt_gio_t {
domain: gio.domain,
id_length: binary_payload.len() as u32,
id: data,
response_code: 0,
response_data_length: 0,
response_data: std::ptr::null::<::std::os::raw::c_uchar>() as *mut c_void,
});

let res = unsafe { cmt_gio_request(fd.0, gio_request.as_mut()) };

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

let mut gio_response: Vec<u8> = Vec::with_capacity(gio_request.response_data_length as usize);
if gio_request.response_data_length == 0 {
log::info!("read zero size response from gio request");
} else {
unsafe {
std::ptr::copy(
gio_request.response_data,
gio_response.as_mut_ptr() as *mut c_void,
gio_request.response_data_length as usize,
);
gio_response.set_len(gio_request.response_data_length as usize);
}
}

let result = GIOResponse {
response_code: gio_request.response_code,
response: "0x".to_string() + &hex::encode(&gio_response),
};
dbg!(result.clone());

Ok(result)
}

pub fn rollup_throw_exception(
fd: &RollupFd,
exception: &Exception,
Expand Down Expand Up @@ -612,7 +701,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 Down
1 change: 0 additions & 1 deletion rollup-http/rollup-http-server/src/rollup/wrapper.h

This file was deleted.

Loading
Loading