cycles-quartz/crates/utils/tcbinfo-updater/src/main.rs

124 lines
4.2 KiB
Rust
Raw Normal View History

2025-02-11 16:43:48 +00:00
use cw_client::{GrpcClient, CwClient};
2024-12-05 13:36:19 +00:00
use quartz_tcbinfo_msgs::{QueryMsg, ExecuteMsg};
2024-12-04 20:35:35 +00:00
use quoted_string::strip_dquotes;
2025-02-11 16:43:48 +00:00
use anyhow::{anyhow, Result};
2024-12-05 14:22:57 +00:00
use quoted_string::test_utils::TestSpec;
use quoted_string::to_content;
2024-12-04 20:35:35 +00:00
use reqwest::Url;
2024-12-03 10:02:58 +00:00
use serde_json::{json, Value};
2024-12-05 16:15:56 +00:00
use std::env;
use tendermint::chain::id::Id;
2024-12-05 13:29:35 +00:00
2024-11-29 19:07:22 +00:00
type Fmspc = String;
type Update = String;
2024-11-29 19:07:22 +00:00
const TCB_SIGNER: &str = include_str!("../tcb_signer.pem");
2024-12-04 19:48:38 +00:00
async fn get_tcbinfo(fmspc: Fmspc, update: Update) -> String {
2024-11-29 19:07:22 +00:00
let url = format!("https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={fmspc}&update={update}");
2024-12-03 09:13:37 +00:00
let body: String = reqwest::get(url)
.await
2024-11-29 19:07:22 +00:00
.expect("url retrieval failed")
.text()
2024-12-03 09:38:50 +00:00
.await
2024-11-29 19:07:22 +00:00
.expect("could not read https response");
2024-12-04 20:35:35 +00:00
body
2024-11-29 19:07:22 +00:00
}
2024-12-03 09:13:37 +00:00
async fn get_fmspc_list() -> Vec<Fmspc> {
2024-11-29 19:07:22 +00:00
let body: String =
2024-12-04 20:35:35 +00:00
reqwest::get("https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs")
.await
.expect("url retrieval failed")
.text()
.await
.expect("could not read https response");
2024-11-29 19:07:22 +00:00
let fmspc_data: Vec<Value> = serde_json::from_str(&body).expect("could not convert to JSON");
let mut fmspc_list: Vec<Fmspc> = Vec::new();
for item in fmspc_data.iter() {
let fmspc: String = format!("{}", item["fmspc"]);
fmspc_list.push(strip_dquotes(&fmspc).unwrap().to_string());
}
fmspc_list
}
2025-02-13 12:27:30 +00:00
async fn upsert_tcbinfo(url: &str, contract_addr: &str, chain_id : Id, sender: &str, gas: u64, fees: &str) -> Result<(), &'static str> {
2024-12-05 12:03:39 +00:00
2025-02-11 16:43:48 +00:00
let network = Url::parse(url).expect("couldn't parse network URL");
let skey = hex::decode(sk).expect("couldn't read signing key")
.as_slice()
.try_into()
.map_err(|e| anyhow!("failed to read/parse sk: {}", e)).expect("couldn't extract result value");
2025-02-13 12:27:30 +00:00
let client = CliClient::new(network);
2024-12-05 12:03:39 +00:00
let fmspc_list = get_fmspc_list().await;
2024-11-29 19:07:22 +00:00
for fmspc in fmspc_list {
2024-12-05 12:03:39 +00:00
let tcbinfo_from_api = get_tcbinfo(fmspc.clone(), "standard".to_string()).await;
2024-12-05 14:28:01 +00:00
2024-12-05 12:03:39 +00:00
// assert!(verify_signature(tcbinfo.clone(), key));
2024-12-05 16:15:56 +00:00
let contract_address = contract_addr
.parse()
2024-12-05 12:03:39 +00:00
.expect("failed to parse contract address");
2024-12-05 13:40:57 +00:00
let query_msg = QueryMsg::GetTcbInfo { fmspc: fmspc.clone() };
2024-12-05 14:47:54 +00:00
let tcbinfo_on_chain = { if let Ok(res) = client.query_smart::<Value>(&contract_address, json!(query_msg)).await {
to_content::<TestSpec>(&res["data"]["tcb_info"].to_string()).unwrap().to_string()
} else {
"".to_string()
}
};
2024-12-05 14:05:29 +00:00
if tcbinfo_on_chain != tcbinfo_from_api {
2024-11-29 19:07:22 +00:00
println!("updating on-chain TCBInfo for FMSPC: {fmspc}");
2024-12-05 16:15:56 +00:00
2024-12-05 12:03:39 +00:00
2024-12-03 09:58:52 +00:00
let execute_msg = ExecuteMsg {
2024-12-05 13:29:35 +00:00
tcb_info: tcbinfo_from_api.to_string(),
certificate: TCB_SIGNER.to_string(),
2024-11-29 19:07:22 +00:00
time: None,
2024-12-03 10:01:17 +00:00
};
2024-12-05 16:15:56 +00:00
let res = client
2024-12-04 20:35:35 +00:00
.tx_execute(
&contract_address,
&chain_id,
2024-12-05 16:15:56 +00:00
gas,
2024-12-05 11:26:03 +00:00
sender,
2024-12-04 20:35:35 +00:00
json!(execute_msg),
2024-12-05 16:15:56 +00:00
fees
2024-12-04 20:35:35 +00:00
)
.await;
2024-12-05 16:15:56 +00:00
println!("{res:?}");
2024-12-03 10:42:57 +00:00
std::thread::sleep(std::time::Duration::from_secs(5));
2024-12-04 20:35:35 +00:00
} else {
2024-11-29 19:07:22 +00:00
println!("TCBInfo for FMSPC: {fmspc} up to date")
2024-11-29 19:07:22 +00:00
}
}
2024-11-29 19:07:22 +00:00
Ok(())
2024-11-29 19:07:22 +00:00
}
2024-11-29 19:07:22 +00:00
2024-12-03 09:13:37 +00:00
#[tokio::main]
pub async fn main() {
2024-12-05 16:15:56 +00:00
let args: Vec<String> = env::args().collect();
let url = &args[1];
let chain_id = &args[2];
let contract_address : &str = &args[3];
let sender: &str = &args[4];
let gas: &u64 = &args[5].parse().expect("gas must be a u64 value");
let fees: &str = &args[6];
2025-02-11 16:43:48 +00:00
let sk: &str = &args[7];
2025-02-13 12:27:30 +00:00
upsert_tcbinfo(url, contract_address, Id::try_from(chain_id.clone()).expect("invalid chain id"), sender, *gas, fees).await.expect("TCBInfo update failed");
2024-11-29 19:07:22 +00:00
}
2024-12-05 16:15:56 +00:00
/*let url =;
let chain_id = tendermint::chain::id::Id::try_from("pion-1").expect("invalid chain id");
contract_address = ;
let sender = ;
gas = 1000000,
fees = ,
*/