Skip to content

Commit

Permalink
Fill out Ethereum functions in the processor Docker tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kayabaNerve committed May 14, 2024
1 parent d27d934 commit af79586
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 57 deletions.
2 changes: 1 addition & 1 deletion tests/docker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub fn build(name: String) {
// Check any additionally specified paths
let meta = |path: PathBuf| (path.clone(), fs::metadata(path));
let mut metadatas = match name.as_str() {
"bitcoin" | "monero" => vec![],
"bitcoin" | "ethereum" | "monero" => vec![],
"message-queue" => vec![
meta(repo_path.join("common")),
meta(repo_path.join("crypto")),
Expand Down
2 changes: 2 additions & 0 deletions tests/processor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, fea
dkg = { path = "../../crypto/dkg", default-features = false, features = ["tests"] }

bitcoin-serai = { path = "../../coins/bitcoin" }
ethereum-serai = { path = "../../coins/ethereum" }
monero-serai = { path = "../../coins/monero" }

messages = { package = "serai-processor-messages", path = "../../processor/messages" }

scale = { package = "parity-scale-codec", version = "3" }
serai-client = { path = "../../substrate/client" }
serai-db = { path = "../../common/db", default-features = false }
serai-message-queue = { path = "../../message-queue" }

borsh = { version = "1", features = ["de_strict_order"] }
Expand Down
194 changes: 142 additions & 52 deletions tests/processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,28 @@ impl Coordinator {
break;
}
}
NetworkId::Ethereum => todo!(),
NetworkId::Ethereum => {
use ethereum_serai::{
alloy_simple_request_transport::SimpleRequest,
alloy_rpc_client::ClientBuilder,
alloy_provider::{Provider, RootProvider},
alloy_network::Ethereum,
};

let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);

loop {
if handle
.block_on(provider.raw_request::<_, ()>("evm_setAutomine".into(), [false]))
.is_ok()
{
break;
}
handle.block_on(tokio::time::sleep(core::time::Duration::from_secs(1)));
}
}
NetworkId::Monero => {
use monero_serai::rpc::HttpRpc;

Expand Down Expand Up @@ -271,7 +292,45 @@ impl Coordinator {
block.consensus_encode(&mut block_buf).unwrap();
(hash, block_buf)
}
NetworkId::Ethereum => todo!(),
NetworkId::Ethereum => {
use ethereum_serai::{
alloy_simple_request_transport::SimpleRequest,
alloy_rpc_types::BlockNumberOrTag,
alloy_rpc_client::ClientBuilder,
alloy_provider::{Provider, RootProvider},
alloy_network::Ethereum,
};

let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);
let start = provider
.get_block(BlockNumberOrTag::Latest.into(), false)
.await
.unwrap()
.unwrap()
.header
.number
.unwrap();
// We mine 96 blocks to mine one epoch, then cause its finalization
provider.raw_request::<_, ()>("anvil_mine".into(), [96]).await.unwrap();
let end_of_epoch = start + 31;
let hash = provider
.get_block(BlockNumberOrTag::Number(end_of_epoch).into(), false)
.await
.unwrap()
.unwrap()
.header
.hash
.unwrap();

let state = provider
.raw_request::<_, String>("anvil_dumpState".into(), ())
.await
.unwrap()
.into_bytes();
(hash.into(), state)
}
NetworkId::Monero => {
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, scalar::Scalar};
use monero_serai::{
Expand Down Expand Up @@ -303,39 +362,6 @@ impl Coordinator {
}
}

pub async fn broadcast_block(&self, ops: &DockerOperations, block: &[u8]) {
let rpc_url = network_rpc(self.network, ops, &self.network_handle);
match self.network {
NetworkId::Bitcoin => {
use bitcoin_serai::rpc::Rpc;

let rpc =
Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC");
let res: Option<String> =
rpc.rpc_call("submitblock", serde_json::json!([hex::encode(block)])).await.unwrap();
if let Some(err) = res {
panic!("submitblock failed: {err}");
}
}
NetworkId::Ethereum => todo!(),
NetworkId::Monero => {
use monero_serai::rpc::HttpRpc;

let rpc =
HttpRpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Monero RPC");
let res: serde_json::Value = rpc
.json_rpc_call("submit_block", Some(serde_json::json!([hex::encode(block)])))
.await
.unwrap();
let err = res.get("error");
if err.is_some() && (err.unwrap() != &serde_json::Value::Null) {
panic!("failed to submit Monero block: {res}");
}
}
NetworkId::Serai => panic!("processor tests broadcasting block to Serai"),
}
}

pub async fn sync(&self, ops: &DockerOperations, others: &[Coordinator]) {
let rpc_url = network_rpc(self.network, ops, &self.network_handle);
match self.network {
Expand All @@ -345,13 +371,8 @@ impl Coordinator {
let rpc = Rpc::new(rpc_url).await.expect("couldn't connect to the Bitcoin RPC");
let to = rpc.get_latest_block_number().await.unwrap();
for coordinator in others {
let from = Rpc::new(network_rpc(self.network, ops, &coordinator.network_handle))
.await
.expect("couldn't connect to the Bitcoin RPC")
.get_latest_block_number()
.await
.unwrap() +
1;
let from = rpc.get_latest_block_number().await.unwrap() + 1;

for b in from ..= to {
let mut buf = vec![];
rpc
Expand All @@ -360,11 +381,40 @@ impl Coordinator {
.unwrap()
.consensus_encode(&mut buf)
.unwrap();
coordinator.broadcast_block(ops, &buf).await;

let rpc_url = network_rpc(coordinator.network, ops, &coordinator.network_handle);
let rpc =
Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC");

let res: Option<String> =
rpc.rpc_call("submitblock", serde_json::json!([hex::encode(buf)])).await.unwrap();
if let Some(err) = res {
panic!("submitblock failed: {err}");
}
}
}
}
NetworkId::Ethereum => todo!(),
NetworkId::Ethereum => {
use ethereum_serai::{
alloy_simple_request_transport::SimpleRequest,
alloy_rpc_client::ClientBuilder,
alloy_provider::{Provider, RootProvider},
alloy_network::Ethereum,
};

let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);
let state = provider.raw_request::<_, String>("anvil_dumpState".into(), ()).await.unwrap();

for coordinator in others {
let rpc_url = network_rpc(coordinator.network, ops, &coordinator.network_handle);
let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);
provider.raw_request::<_, ()>("anvil_loadState".into(), &state).await.unwrap();
}
}
NetworkId::Monero => {
use monero_serai::rpc::HttpRpc;

Expand All @@ -378,12 +428,21 @@ impl Coordinator {
.await
.unwrap();
for b in from .. to {
coordinator
.broadcast_block(
ops,
&rpc.get_block(rpc.get_block_hash(b).await.unwrap()).await.unwrap().serialize(),
)
.await;
let block =
rpc.get_block(rpc.get_block_hash(b).await.unwrap()).await.unwrap().serialize();

let rpc_url = network_rpc(coordinator.network, ops, &coordinator.network_handle);
let rpc = HttpRpc::new(rpc_url)
.await
.expect("couldn't connect to the coordinator's Monero RPC");
let res: serde_json::Value = rpc
.json_rpc_call("submit_block", Some(serde_json::json!([hex::encode(block)])))
.await
.unwrap();
let err = res.get("error");
if err.is_some() && (err.unwrap() != &serde_json::Value::Null) {
panic!("failed to submit Monero block: {res}");
}
}
}
}
Expand All @@ -404,7 +463,19 @@ impl Coordinator {
Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC");
rpc.send_raw_transaction(&Transaction::consensus_decode(&mut &*tx).unwrap()).await.unwrap();
}
NetworkId::Ethereum => todo!(),
NetworkId::Ethereum => {
use ethereum_serai::{
alloy_simple_request_transport::SimpleRequest,
alloy_rpc_client::ClientBuilder,
alloy_provider::{Provider, RootProvider},
alloy_network::Ethereum,
};

let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);
let _ = provider.send_raw_transaction(tx).await.unwrap();
}
NetworkId::Monero => {
use monero_serai::{transaction::Transaction, rpc::HttpRpc};

Expand Down Expand Up @@ -445,7 +516,26 @@ impl Coordinator {
None
}
}
NetworkId::Ethereum => todo!(),
NetworkId::Ethereum => {
use ethereum_serai::{
alloy_simple_request_transport::SimpleRequest,
alloy_consensus::{TxLegacy, Signed},
alloy_rpc_client::ClientBuilder,
alloy_provider::{Provider, RootProvider},
alloy_network::Ethereum,
};

let provider = RootProvider::<_, Ethereum>::new(
ClientBuilder::default().transport(SimpleRequest::new(rpc_url.clone()), true),
);
let mut hash = [0; 32];
hash.copy_from_slice(tx);
let tx = provider.get_transaction_by_hash(hash.into()).await.unwrap()?;
let (tx, sig, _) = Signed::<TxLegacy>::try_from(tx).unwrap().into_parts();
let mut bytes = vec![];
tx.encode_with_signature_fields(&sig, &mut bytes);
Some(bytes)
}
NetworkId::Monero => {
use monero_serai::rpc::HttpRpc;

Expand Down
Loading

0 comments on commit af79586

Please sign in to comment.