Finish the Ethereum TX publishing code

This commit is contained in:
Luke Parker
2024-09-19 00:39:51 -04:00
parent e75c4ec6ed
commit 118d81bc90
3 changed files with 39 additions and 36 deletions

View File

@@ -1,4 +1,4 @@
# Ethereum Transaction Relayer # Ethereum Transaction Relayer
This server collects Ethereum router commands to be published, offering an RPC This server collects Ethereum transactions to be published, offering an RPC to
to fetch them. fetch them.

View File

@@ -40,8 +40,8 @@ async fn main() {
db db
}; };
// Start command recipience server // Start transaction recipience server
// This should not be publicly exposed // This MUST NOT be publicly exposed
// TODO: Add auth // TODO: Add auth
tokio::spawn({ tokio::spawn({
let db = db.clone(); let db = db.clone();
@@ -58,25 +58,27 @@ async fn main() {
let mut buf = vec![0; usize::try_from(msg_len).unwrap()]; let mut buf = vec![0; usize::try_from(msg_len).unwrap()];
let Ok(_) = socket.read_exact(&mut buf).await else { break }; let Ok(_) = socket.read_exact(&mut buf).await else { break };
if buf.len() < 5 { if buf.len() < (4 + 1) {
break; break;
} }
let nonce = u32::from_le_bytes(buf[.. 4].try_into().unwrap()); let nonce = u32::from_le_bytes(buf[.. 4].try_into().unwrap());
let mut txn = db.txn(); let mut txn = db.txn();
// Save the transaction
txn.put(nonce.to_le_bytes(), &buf[4 ..]); txn.put(nonce.to_le_bytes(), &buf[4 ..]);
txn.commit(); txn.commit();
let Ok(()) = socket.write_all(&[1]).await else { break }; let Ok(()) = socket.write_all(&[1]).await else { break };
log::info!("received signed command #{nonce}"); log::info!("received transaction to publish (nonce {nonce})");
} }
}); });
} }
} }
}); });
// Start command fetch server // Start transaction fetch server
// 5132 ^ ((b'E' << 8) | b'R') + 1 // 5132 ^ ((b'E' << 8) | b'R') + 1
// TODO: JSON-RPC server which returns this as JSON?
let server = TcpListener::bind("0.0.0.0:20831").await.unwrap(); let server = TcpListener::bind("0.0.0.0:20831").await.unwrap();
loop { loop {
let (mut socket, _) = server.accept().await.unwrap(); let (mut socket, _) = server.accept().await.unwrap();
@@ -84,16 +86,16 @@ async fn main() {
tokio::spawn(async move { tokio::spawn(async move {
let db = db.clone(); let db = db.clone();
loop { loop {
// Nonce to get the router comamnd for // Nonce to get the unsigned transaction for
let mut buf = vec![0; 4]; let mut buf = vec![0; 4];
let Ok(_) = socket.read_exact(&mut buf).await else { break }; let Ok(_) = socket.read_exact(&mut buf).await else { break };
let command = db.get(&buf[.. 4]).unwrap_or(vec![]); let transaction = db.get(&buf[.. 4]).unwrap_or(vec![]);
let Ok(()) = socket.write_all(&u32::try_from(command.len()).unwrap().to_le_bytes()).await let Ok(()) = socket.write_all(&u32::try_from(transaction.len()).unwrap().to_le_bytes()).await
else { else {
break; break;
}; };
let Ok(()) = socket.write_all(&command).await else { break }; let Ok(()) = socket.write_all(&transaction).await else { break };
} }
}); });
} }

View File

@@ -1,11 +1,17 @@
use core::future::Future; use core::future::Future;
use std::sync::Arc; use std::sync::Arc;
use alloy_rlp::Encodable;
use alloy_transport::{TransportErrorKind, RpcError}; use alloy_transport::{TransportErrorKind, RpcError};
use alloy_simple_request_transport::SimpleRequest; use alloy_simple_request_transport::SimpleRequest;
use alloy_provider::RootProvider; use alloy_provider::RootProvider;
use tokio::sync::{RwLockReadGuard, RwLock}; use tokio::{
sync::{RwLockReadGuard, RwLock},
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
use ethereum_schnorr::PublicKey; use ethereum_schnorr::PublicKey;
use ethereum_router::{OutInstructions, Router}; use ethereum_router::{OutInstructions, Router};
@@ -62,9 +68,11 @@ impl signers::TransactionPublisher<Transaction> for TransactionPublisher {
tx: Transaction, tx: Transaction,
) -> impl Send + Future<Output = Result<(), Self::EphemeralError>> { ) -> impl Send + Future<Output = Result<(), Self::EphemeralError>> {
async move { async move {
// Convert from an Action (an internal representation of a signable event) to a TxLegacy
let router = self.router().await?; let router = self.router().await?;
let router = router.as_ref().unwrap(); let router = router.as_ref().unwrap();
let nonce = tx.0.nonce();
// Convert from an Action (an internal representation of a signable event) to a TxLegacy
let tx = match tx.0 { let tx = match tx.0 {
Action::SetKey { chain_id: _, nonce: _, key } => router.update_serai_key(&key, &tx.1), Action::SetKey { chain_id: _, nonce: _, key } => router.update_serai_key(&key, &tx.1),
Action::Batch { chain_id: _, nonce: _, outs } => { Action::Batch { chain_id: _, nonce: _, outs } => {
@@ -72,40 +80,33 @@ impl signers::TransactionPublisher<Transaction> for TransactionPublisher {
} }
}; };
/* // Nonce
use tokio::{ let mut msg = nonce.to_le_bytes().to_vec();
io::{AsyncReadExt, AsyncWriteExt}, // Transaction
net::TcpStream, tx.encode(&mut msg);
};
let mut msg = vec![];
match completion.command() {
RouterCommand::UpdateSeraiKey { nonce, .. } | RouterCommand::Execute { nonce, .. } => {
msg.extend(&u32::try_from(nonce).unwrap().to_le_bytes());
}
}
completion.write(&mut msg).unwrap();
let Ok(mut socket) = TcpStream::connect(&self.relayer_url).await else { let Ok(mut socket) = TcpStream::connect(&self.relayer_url).await else {
log::warn!("couldn't connect to the relayer server"); Err(TransportErrorKind::Custom(
Err(NetworkError::ConnectionError)? "couldn't connect to the relayer server".to_string().into(),
))?
}; };
let Ok(()) = socket.write_all(&u32::try_from(msg.len()).unwrap().to_le_bytes()).await else { let Ok(()) = socket.write_all(&u32::try_from(msg.len()).unwrap().to_le_bytes()).await else {
log::warn!("couldn't send the message's len to the relayer server"); Err(TransportErrorKind::Custom(
Err(NetworkError::ConnectionError)? "couldn't send the message's len to the relayer server".to_string().into(),
))?
}; };
let Ok(()) = socket.write_all(&msg).await else { let Ok(()) = socket.write_all(&msg).await else {
log::warn!("couldn't write the message to the relayer server"); Err(TransportErrorKind::Custom(
Err(NetworkError::ConnectionError)? "couldn't write the message to the relayer server".to_string().into(),
))?
}; };
if socket.read_u8().await.ok() != Some(1) { if socket.read_u8().await.ok() != Some(1) {
log::warn!("didn't get the ack from the relayer server"); Err(TransportErrorKind::Custom(
Err(NetworkError::ConnectionError)?; "didn't get the ack from the relayer server".to_string().into(),
))?;
} }
Ok(()) Ok(())
*/
todo!("TODO")
} }
} }
} }