Skip to content

Commit

Permalink
run server to retrieve bill info
Browse files Browse the repository at this point in the history
  • Loading branch information
Ayush-Yadav committed Feb 7, 2024
1 parent 4c2911e commit 5b1cc2d
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 150 deletions.
33 changes: 33 additions & 0 deletions src/bill_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::model::AppState;

use actix_web::{web::Data, HttpResponse};
use anyhow::Context;
use k256::elliptic_curve::generic_array::sequence::Lengthen;
use serde_json::json;
use tiny_keccak::{Hasher, Keccak};

pub async fn bill_data(appstate: Data<AppState>) -> HttpResponse {
let mut costs_gaurd = appstate.execution_costs.lock().unwrap();
let costs_map = costs_gaurd.clone();

let mut hash = [0u8; 32];
let mut hasher_gaurd = appstate.billing_hasher.lock().unwrap();
hasher_gaurd.clone().finalize(&mut hash);
let sign = appstate
.signer
.sign_prehash_recoverable(&hash)
.context("Failed to sign requests data");
if sign.is_err() {
return HttpResponse::InternalServerError().body(format!("{:?}", sign.unwrap_err()));
}
let (rs, v) = sign.unwrap();
let signature = hex::encode(rs.to_bytes().append(27 + v.to_byte()).as_slice());

costs_gaurd.clear();
hasher_gaurd.clone_from(&Keccak::v256());

HttpResponse::Ok().json(json!({
"execution_costs": costs_map,
"signature": signature,
}))
}
73 changes: 0 additions & 73 deletions src/billing_job.rs

This file was deleted.

20 changes: 12 additions & 8 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::time::{Duration, Instant};
use crate::{cgroups, model::AppState, workerd};

use actix_web::http::{header, StatusCode};
use actix_web::{HttpRequest, HttpResponse, Responder, web};
use actix_web::{web, HttpRequest, HttpResponse, Responder};
use anyhow::{anyhow, Context};
use tiny_keccak::Hasher;
use tokio::time::timeout;
Expand Down Expand Up @@ -68,7 +68,6 @@ pub async fn serverless(
&appstate.rpc,
&appstate.contract,
&appstate.billing_contract,
&appstate.abi,
)
.await
{
Expand Down Expand Up @@ -272,14 +271,19 @@ pub async fn serverless(
let execution_time = execution_timer_end
.duration_since(execution_timer_start)
.as_millis();

// TODO: FIX THE VALUE OF FIXED COST AND CONVERSION RATE
let execution_cost = 1 + 2*execution_time;
let mut costs_guard = appstate.execution_costs.lock().await;
let amount = costs_guard.entry(tx_hash.to_string()).or_insert(0);
*amount += execution_cost;
let execution_cost = 1 + 2 * execution_time;

appstate
.execution_costs
.lock()
.unwrap()
.entry(tx_hash.to_owned())
.and_modify(|cost| *cost += execution_cost)
.or_insert(execution_cost);

appstate.billing_hasher.lock().await.update(&hash);
appstate.billing_hasher.lock().unwrap().update(&hash);

return response;
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod billing_job;
pub mod bill_handler;
pub mod cgroups;
pub mod handler;
pub mod model;
Expand Down
51 changes: 18 additions & 33 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use std::collections::HashMap;

use serverless::billing_job::billing_scheduler;
use serverless::cgroups::Cgroups;
use serverless::model::AppState;

use actix_web::{App, HttpServer, web};
use actix_web::{web, App, HttpServer};
use anyhow::{anyhow, Context};
use clap::Parser;
use ethers::abi::Abi;
use tiny_keccak::Keccak;
use tokio::fs;
use tokio::time::{Duration, interval};

/// Simple program to greet a person
#[derive(Parser, Debug)]
Expand All @@ -19,6 +16,9 @@ struct Args {
#[clap(long, value_parser, default_value = "6001")]
port: u16,

#[clap(long, value_parser)]
bill_port: u16, // TODO: ADD THE DEFAULT PORT

#[clap(long, value_parser, default_value = "./runtime/")]
runtime_path: String,

Expand All @@ -40,10 +40,7 @@ struct Args {
contract: String,

#[clap(long, value_parser)]
billing_contract: String,

#[clap(long, value_parser)]
operator_wallet_key: String,
billing_contract: String, // TODO: ADD A DEFAULT ADDRESS

#[clap(long, value_parser)]
signer: String,
Expand All @@ -64,6 +61,7 @@ async fn main() -> anyhow::Result<()> {
// println!("{:?}", response);

let port: u16 = cli.port;
let bill_port: u16 = cli.bill_port;

let cgroups = Cgroups::new().context("failed to construct cgroups")?;
if cgroups.free.is_empty() {
Expand All @@ -77,12 +75,6 @@ async fn main() -> anyhow::Result<()> {
.as_slice(),
)
.context("invalid signer key")?;

let abi_json_string = fs::read_to_string("src/contract_abi.json")
.await
.context("failed to read contract ABI")?;
let abi = serde_json::from_str::<Abi>(&abi_json_string)
.context("failed to deserialize ABI")?;

let app_data = web::Data::new(AppState {
cgroups: cgroups.into(),
Expand All @@ -92,8 +84,6 @@ async fn main() -> anyhow::Result<()> {
contract: cli.contract,
billing_contract: cli.billing_contract,
signer: signer,
abi: abi,
operator_wallet_key: cli.operator_wallet_key,
execution_costs: HashMap::new().into(),
billing_hasher: Keccak::v256().into(),
});
Expand All @@ -110,23 +100,18 @@ async fn main() -> anyhow::Result<()> {

println!("Server started on port {}", port);

server.await?;

tokio::spawn(async move {
// TODO: FIX THE REGULAR INTERVAL
let mut interval = interval(Duration::from_secs(600));
loop {
interval.tick().await;

if !app_data_clone.execution_costs.lock().await.is_empty() {

match billing_scheduler(app_data_clone.clone()).await {
Ok(tx_hash) => println!("Transaction sent for billing: {}", tx_hash),
Err(err) => println!("Error while sending billing transaction: {:?}", err),
}
}
}
});
let bill_server = HttpServer::new(move || {
App::new()
.app_data(app_data_clone.clone())
.default_service(web::to(serverless::bill_handler::bill_data))
})
.bind(("0.0.0.0", bill_port))
.context(format!("could not bind to port {bill_port}"))?
.run();

println!("Bill Server started on port {}", bill_port);

tokio::try_join!(server, bill_server)?;

Ok(())
}
8 changes: 2 additions & 6 deletions src/model.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use std::sync::atomic::AtomicBool;
use std::collections::HashMap;
use std::sync::{atomic::AtomicBool, Mutex};

use crate::cgroups::Cgroups;

use ethers::abi::Abi;
use tiny_keccak::Keccak;
use tokio::sync::Mutex;

pub struct AppState {
pub cgroups: std::sync::Mutex<Cgroups>,
pub cgroups: Mutex<Cgroups>,
// IMPORTANT: we use Relaxed ordering here since we do not need to synchronize any memory
// not even with reads/writes to the same atomic (we just serve a few more requests at worst)
// be very careful adding more operations associated with the draining state
Expand All @@ -18,8 +16,6 @@ pub struct AppState {
pub contract: String,
pub billing_contract: String,
pub signer: k256::ecdsa::SigningKey,
pub abi: Abi,
pub operator_wallet_key: String,
pub execution_costs: Mutex<HashMap<String, u128>>,
pub billing_hasher: Mutex<Keccak>,
}
14 changes: 3 additions & 11 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#[cfg(test)]
pub mod serverlesstest {
use std::{collections::HashMap, fs::File, io::Read, sync::atomic::AtomicBool};
use crate::cgroups::Cgroups;
use crate::handler;
use crate::model::AppState;
Expand All @@ -15,8 +14,8 @@ pub mod serverlesstest {
error::Error,
http, test, web, App,
};
use ethers::abi::Abi;
use serde_json::json;
use std::{collections::HashMap, sync::atomic::AtomicBool};
use tiny_keccak::Keccak;

fn new_app() -> App<
Expand All @@ -27,23 +26,16 @@ pub mod serverlesstest {
InitError = (),
Error = Error,
>,
> {
let mut abi_json = String::new();
let mut file = File::open("src/contract_abi.json").unwrap();
file.read_to_string(&mut abi_json).unwrap();
let abi = serde_json::from_str::<Abi>(&abi_json).unwrap();

> {
App::new()
.app_data(web::Data::new(AppState {
cgroups: Cgroups::new().unwrap().into(),
running: AtomicBool::new(true),
runtime_path: "./runtime/".to_owned(),
rpc: "https://sepolia-rollup.arbitrum.io/rpc".to_owned(),
contract: "0x44fe06d2940b8782a0a9a9ffd09c65852c0156b1".to_owned(),
billing_contract: String::new(), // TODO: ADD BILLING CONTRACT FOR TESTS
abi: abi,
billing_contract: String::new(), // TODO: ADD BILLING CONTRACT FOR TESTS
signer: k256::ecdsa::SigningKey::random(&mut rand::rngs::OsRng),
operator_wallet_key: String::new(), //TODO: ADD A WALLET KEY FOR RUNNING TESTS
execution_costs: HashMap::new().into(),
billing_hasher: Keccak::v256().into(),
}))
Expand Down
Loading

0 comments on commit 5b1cc2d

Please sign in to comment.