2024-09-14 07:54:18 -04:00
|
|
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
|
|
|
|
#![doc = include_str!("../README.md")]
|
|
|
|
|
#![deny(missing_docs)]
|
|
|
|
|
|
|
|
|
|
#[global_allocator]
|
|
|
|
|
static ALLOCATOR: zalloc::ZeroizingAlloc<std::alloc::System> =
|
|
|
|
|
zalloc::ZeroizingAlloc(std::alloc::System);
|
|
|
|
|
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
2024-09-18 00:54:20 -04:00
|
|
|
use alloy_core::primitives::U256;
|
|
|
|
|
use alloy_simple_request_transport::SimpleRequest;
|
|
|
|
|
use alloy_rpc_client::ClientBuilder;
|
|
|
|
|
use alloy_provider::{Provider, RootProvider};
|
2024-09-14 07:54:18 -04:00
|
|
|
|
2024-09-19 01:31:52 -04:00
|
|
|
use serai_client::validator_sets::primitives::Session;
|
|
|
|
|
|
2024-09-14 07:54:18 -04:00
|
|
|
use serai_env as env;
|
2024-09-19 01:31:52 -04:00
|
|
|
use serai_db::{Get, DbTxn, create_db};
|
|
|
|
|
|
|
|
|
|
use ::primitives::EncodableG;
|
|
|
|
|
use ::key_gen::KeyGenParams as KeyGenParamsTrait;
|
2024-09-14 07:54:18 -04:00
|
|
|
|
|
|
|
|
mod primitives;
|
|
|
|
|
pub(crate) use crate::primitives::*;
|
|
|
|
|
|
|
|
|
|
mod key_gen;
|
|
|
|
|
use crate::key_gen::KeyGenParams;
|
|
|
|
|
mod rpc;
|
|
|
|
|
use rpc::Rpc;
|
|
|
|
|
mod scheduler;
|
|
|
|
|
use scheduler::{SmartContract, Scheduler};
|
|
|
|
|
mod publisher;
|
|
|
|
|
use publisher::TransactionPublisher;
|
|
|
|
|
|
2024-09-19 01:31:52 -04:00
|
|
|
create_db! {
|
|
|
|
|
EthereumProcessor {
|
|
|
|
|
// The initial key for Serai on Ethereum
|
|
|
|
|
InitialSeraiKey: () -> EncodableG<k256::ProjectivePoint>,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct SetInitialKey;
|
|
|
|
|
impl bin::Hooks for SetInitialKey {
|
|
|
|
|
fn on_message(txn: &mut impl DbTxn, msg: &messages::CoordinatorMessage) {
|
|
|
|
|
if let messages::CoordinatorMessage::Substrate(
|
|
|
|
|
messages::substrate::CoordinatorMessage::SetKeys { session, key_pair, .. },
|
|
|
|
|
) = msg
|
|
|
|
|
{
|
|
|
|
|
assert_eq!(*session, Session(0));
|
|
|
|
|
let key = KeyGenParams::decode_key(key_pair.1.as_ref())
|
|
|
|
|
.expect("invalid Ethereum key confirmed on Substrate");
|
|
|
|
|
InitialSeraiKey::set(txn, &EncodableG(key));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 07:54:18 -04:00
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() {
|
|
|
|
|
let db = bin::init();
|
2024-09-18 15:50:21 -04:00
|
|
|
|
|
|
|
|
let provider = Arc::new(RootProvider::new(
|
|
|
|
|
ClientBuilder::default().transport(SimpleRequest::new(bin::url()), true),
|
|
|
|
|
));
|
|
|
|
|
|
2024-09-14 07:54:18 -04:00
|
|
|
let chain_id = loop {
|
2024-09-18 15:50:21 -04:00
|
|
|
match provider.get_chain_id().await {
|
2024-09-14 07:54:18 -04:00
|
|
|
Ok(chain_id) => break U256::try_from(chain_id).unwrap(),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
log::error!("couldn't connect to the Ethereum node for the chain ID: {e:?}");
|
|
|
|
|
tokio::time::sleep(core::time::Duration::from_secs(5)).await;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-19 01:31:52 -04:00
|
|
|
bin::main_loop::<SetInitialKey, _, KeyGenParams, _>(
|
|
|
|
|
db.clone(),
|
2024-09-18 15:50:21 -04:00
|
|
|
Rpc { provider: provider.clone() },
|
2024-09-14 07:54:18 -04:00
|
|
|
Scheduler::new(SmartContract { chain_id }),
|
2024-09-19 01:31:52 -04:00
|
|
|
TransactionPublisher::new(db, provider, {
|
2024-09-14 07:54:18 -04:00
|
|
|
let relayer_hostname = env::var("ETHEREUM_RELAYER_HOSTNAME")
|
|
|
|
|
.expect("ethereum relayer hostname wasn't specified")
|
|
|
|
|
.to_string();
|
|
|
|
|
let relayer_port =
|
|
|
|
|
env::var("ETHEREUM_RELAYER_PORT").expect("ethereum relayer port wasn't specified");
|
|
|
|
|
relayer_hostname + ":" + &relayer_port
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
|
}
|