use std::{env, sync::Arc};
use anyhow::Result;
use async_trait::async_trait;
use linera_base::data_types::Amount;
use linera_client::persistent::{self, Persist};
use tempfile::{tempdir, TempDir};
use super::{
local_net::PathProvider, ClientWrapper, Faucet, FaucetOption, LineraNet, LineraNetConfig,
Network, OnClientDrop,
};
pub struct RemoteNetTestingConfig {
faucet: Faucet,
}
impl RemoteNetTestingConfig {
pub fn new(faucet_url: Option<String>) -> Self {
Self {
faucet: Faucet::new(
faucet_url
.or_else(|| env::var("LINERA_FAUCET_URL").ok())
.expect("Missing `LINERA_FAUCET_URL` environment variable"),
),
}
}
}
#[async_trait]
impl LineraNetConfig for RemoteNetTestingConfig {
type Net = RemoteNet;
async fn instantiate(self) -> Result<(Self::Net, ClientWrapper)> {
let seed = 37;
let mut net = RemoteNet::new(Some(seed), &self.faucet)
.await
.expect("Creating RemoteNet should not fail");
let client = net.make_client().await;
client
.wallet_init(&[], FaucetOption::NewChain(&self.faucet))
.await
.unwrap();
for _ in 0..2 {
client
.open_and_assign(&client, Amount::from_tokens(10))
.await
.unwrap();
}
Ok((net, client))
}
}
#[derive(Clone)]
pub struct RemoteNet {
network: Network,
testing_prng_seed: Option<u64>,
next_client_id: usize,
tmp_dir: Arc<TempDir>,
}
#[async_trait]
impl LineraNet for RemoteNet {
async fn ensure_is_running(&mut self) -> Result<()> {
Ok(())
}
async fn make_client(&mut self) -> ClientWrapper {
let path_provider = PathProvider::TemporaryDirectory {
tmp_dir: self.tmp_dir.clone(),
};
let client = ClientWrapper::new(
path_provider,
self.network,
self.testing_prng_seed,
self.next_client_id,
OnClientDrop::CloseChains,
);
if let Some(seed) = self.testing_prng_seed {
self.testing_prng_seed = Some(seed + 1);
}
self.next_client_id += 1;
client
}
async fn terminate(&mut self) -> Result<()> {
Ok(())
}
}
impl RemoteNet {
async fn new(testing_prng_seed: Option<u64>, faucet: &Faucet) -> Result<Self> {
let tmp_dir = Arc::new(tempdir()?);
persistent::File::new(
tmp_dir.path().join("genesis.json").as_path(),
faucet.genesis_config().await?,
)?
.persist()
.await?;
Ok(Self {
network: Network::Grpc,
testing_prng_seed,
next_client_id: 0,
tmp_dir,
})
}
}