Skip to content

Commit dde98a8

Browse files
committed
Apply review comments.
1 parent 9536e4c commit dde98a8

3 files changed

Lines changed: 81 additions & 63 deletions

File tree

linera-faucet/server/src/lib.rs

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ pub struct QueryRoot<C> {
5050

5151
/// The root GraphQL mutation type.
5252
pub struct MutationRoot<C> {
53+
/// The chain from which new faucet chains are opened.
5354
main_chain_id: ChainId,
54-
tmp_chain_id: Arc<Mutex<Option<ChainId>>>,
55+
/// The chain that is currently used to open requested chains for clients.
56+
faucet_chain_id: Arc<Mutex<Option<ChainId>>>,
5557
context: Arc<Mutex<C>>,
5658
amount: Amount,
57-
max_claims_per_chain: u32,
59+
faucet_init_balance: Amount,
5860
end_timestamp: Timestamp,
5961
start_timestamp: Timestamp,
6062
start_balance: Amount,
@@ -123,54 +125,28 @@ where
123125
C: ClientContext,
124126
{
125127
async fn do_claim(&self, owner: AccountOwner) -> Result<ClaimOutcome, Error> {
126-
let main_client = self
127-
.context
128-
.lock()
129-
.await
130-
.make_chain_client(self.main_chain_id)?;
131-
let maybe_tmp_chain_id = *self.tmp_chain_id.lock().await;
132-
let main_balance = main_client.local_balance().await?;
133-
let tmp_chain_id = match maybe_tmp_chain_id {
134-
Some(tmp_chain_id) => tmp_chain_id,
135-
None => {
136-
let key_pair = main_client.key_pair().await?;
137-
let balance = self
138-
.amount
139-
.try_add(MAX_FEE)?
140-
.try_mul(u128::from(self.max_claims_per_chain))?
141-
.try_add(MAX_FEE)? // One more block fee for closing the chain.
142-
.min(main_balance.try_sub(MAX_FEE)?);
143-
let ownership = main_client.chain_state_view().await?.ownership().clone();
144-
let (message_id, certificate) = main_client
145-
.open_chain(ownership, ApplicationPermissions::default(), balance)
146-
.await?
147-
.try_unwrap()?;
148-
let chain_id = ChainId::child(message_id);
149-
info!("Switching to a new faucet chain {chain_id:8}");
150-
self.context
151-
.lock()
152-
.await
153-
.update_wallet_for_new_chain(
154-
chain_id,
155-
Some(key_pair),
156-
certificate.block().header.timestamp,
157-
)
158-
.await?;
159-
*self.tmp_chain_id.lock().await = Some(chain_id);
160-
chain_id
161-
}
128+
let maybe_faucet_chain_id = *self.faucet_chain_id.lock().await;
129+
let faucet_chain_id = match maybe_faucet_chain_id {
130+
Some(faucet_chain_id) => faucet_chain_id,
131+
None => self.open_new_faucet_chain().await?,
132+
};
133+
let (faucet_client, main_client) = {
134+
let guard = self.context.lock().await;
135+
(
136+
guard.make_chain_client(faucet_chain_id)?,
137+
guard.make_chain_client(self.main_chain_id)?,
138+
)
162139
};
163-
let tmp_client = self.context.lock().await.make_chain_client(tmp_chain_id)?;
164140

165141
if self.start_timestamp < self.end_timestamp {
166-
let local_time = tmp_client.storage_client().clock().current_time();
142+
let local_time = faucet_client.storage_client().clock().current_time();
167143
if local_time < self.end_timestamp {
168144
let full_duration = self
169145
.end_timestamp
170146
.delta_since(self.start_timestamp)
171147
.as_micros();
172148
let remaining_duration = self.end_timestamp.delta_since(local_time).as_micros();
173-
let balance = tmp_client
149+
let balance = faucet_client
174150
.local_balance()
175151
.await?
176152
.try_add(main_client.local_balance().await?)?;
@@ -190,27 +166,31 @@ where
190166
}
191167

192168
let ownership = ChainOwnership::single(owner);
193-
let result = tmp_client
169+
let (message_id, certificate) = faucet_client
194170
.open_chain(ownership, ApplicationPermissions::default(), self.amount)
195-
.await;
196-
self.context.lock().await.update_wallet(&tmp_client).await?;
197-
let (message_id, certificate) = result?.try_unwrap()?;
171+
.await?
172+
.try_unwrap()?;
173+
self.context
174+
.lock()
175+
.await
176+
.update_wallet(&faucet_client)
177+
.await?;
198178

199179
// Only keep using this chain if there will still be enough balance to close it.
200-
if tmp_client.local_balance().await? < self.amount.try_add(MAX_FEE.try_mul(2)?)? {
180+
if faucet_client.local_balance().await? < self.amount.try_add(MAX_FEE.try_mul(2)?)? {
201181
// TODO(#1795): Move the remaining tokens back to the main chain.
202-
match tmp_client.close_chain().await {
182+
match faucet_client.close_chain().await {
203183
Ok(outcome) => {
204184
outcome.try_unwrap()?;
205185
}
206-
Err(err) => tracing::warn!("Failed to close the chain: {err:?}"),
186+
Err(err) => tracing::warn!("Failed to close the temporary faucet chain: {err:?}"),
207187
}
208188
self.context
209189
.lock()
210190
.await
211-
.forget_chain(&tmp_chain_id)
191+
.forget_chain(&faucet_chain_id)
212192
.await?;
213-
self.tmp_chain_id.lock().await.take();
193+
self.faucet_chain_id.lock().await.take();
214194
}
215195

216196
let chain_id = ChainId::child(message_id);
@@ -220,6 +200,35 @@ where
220200
certificate_hash: certificate.hash(),
221201
})
222202
}
203+
204+
async fn open_new_faucet_chain(&self) -> Result<ChainId, Error> {
205+
let main_client = self
206+
.context
207+
.lock()
208+
.await
209+
.make_chain_client(self.main_chain_id)?;
210+
let main_balance = main_client.local_balance().await?;
211+
let key_pair = main_client.key_pair().await?;
212+
let balance = self.faucet_init_balance.min(main_balance.try_sub(MAX_FEE)?);
213+
let ownership = main_client.chain_state_view().await?.ownership().clone();
214+
let (message_id, certificate) = main_client
215+
.open_chain(ownership, ApplicationPermissions::default(), balance)
216+
.await?
217+
.try_unwrap()?;
218+
let chain_id = ChainId::child(message_id);
219+
info!("Switching to a new faucet chain {chain_id:8}");
220+
self.context
221+
.lock()
222+
.await
223+
.update_wallet_for_new_chain(
224+
chain_id,
225+
Some(key_pair),
226+
certificate.block().header.timestamp,
227+
)
228+
.await?;
229+
*self.faucet_chain_id.lock().await = Some(chain_id);
230+
Ok(chain_id)
231+
}
223232
}
224233

225234
impl<C> MutationRoot<C> {
@@ -240,15 +249,15 @@ where
240249
C: ClientContext,
241250
{
242251
main_chain_id: ChainId,
243-
tmp_chain_id: Arc<Mutex<Option<ChainId>>>,
252+
faucet_chain_id: Arc<Mutex<Option<ChainId>>>,
244253
context: Arc<Mutex<C>>,
245254
genesis_config: Arc<GenesisConfig>,
246255
config: ChainListenerConfig,
247256
storage: C::Storage,
248257
port: NonZeroU16,
249258
amount: Amount,
250259
end_timestamp: Timestamp,
251-
max_claims_per_chain: u32,
260+
faucet_init_balance: Amount,
252261
start_timestamp: Timestamp,
253262
start_balance: Amount,
254263
}
@@ -260,14 +269,14 @@ where
260269
fn clone(&self) -> Self {
261270
Self {
262271
main_chain_id: self.main_chain_id,
263-
tmp_chain_id: Arc::clone(&self.tmp_chain_id),
272+
faucet_chain_id: Arc::clone(&self.faucet_chain_id),
264273
context: Arc::clone(&self.context),
265274
genesis_config: Arc::clone(&self.genesis_config),
266275
config: self.config.clone(),
267276
storage: self.storage.clone(),
268277
port: self.port,
269278
amount: self.amount,
270-
max_claims_per_chain: self.max_claims_per_chain,
279+
faucet_init_balance: self.faucet_init_balance,
271280
end_timestamp: self.end_timestamp,
272281
start_timestamp: self.start_timestamp,
273282
start_balance: self.start_balance,
@@ -292,21 +301,25 @@ where
292301
config: ChainListenerConfig,
293302
storage: C::Storage,
294303
) -> anyhow::Result<Self> {
304+
let faucet_init_balance = amount
305+
.try_add(MAX_FEE)?
306+
.try_mul(u128::from(max_claims_per_chain))?
307+
.try_add(MAX_FEE)?; // One more block fee for closing the chain.
295308
let client = context.make_chain_client(chain_id)?;
296309
let context = Arc::new(Mutex::new(context));
297310
let start_timestamp = client.storage_client().clock().current_time();
298311
client.process_inbox().await?;
299312
let start_balance = client.local_balance().await?;
300313
Ok(Self {
301314
main_chain_id: chain_id,
302-
tmp_chain_id: Arc::new(Mutex::new(None)),
315+
faucet_chain_id: Arc::new(Mutex::new(None)),
303316
context,
304317
genesis_config,
305318
config,
306319
storage,
307320
port,
308321
amount,
309-
max_claims_per_chain,
322+
faucet_init_balance,
310323
end_timestamp,
311324
start_timestamp,
312325
start_balance,
@@ -316,10 +329,10 @@ where
316329
pub fn schema(&self) -> Schema<QueryRoot<C>, MutationRoot<C>, EmptySubscription> {
317330
let mutation_root = MutationRoot {
318331
main_chain_id: self.main_chain_id,
319-
tmp_chain_id: Arc::clone(&self.tmp_chain_id),
332+
faucet_chain_id: Arc::clone(&self.faucet_chain_id),
320333
context: Arc::clone(&self.context),
321334
amount: self.amount,
322-
max_claims_per_chain: self.max_claims_per_chain,
335+
faucet_init_balance: self.faucet_init_balance,
323336
end_timestamp: self.end_timestamp,
324337
start_timestamp: self.start_timestamp,
325338
start_balance: self.start_balance,

linera-faucet/server/src/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ async fn test_faucet_rate_limiting() {
9090
let context = Arc::new(Mutex::new(context));
9191
let root = MutationRoot {
9292
main_chain_id,
93-
tmp_chain_id: Arc::new(Mutex::new(Some(chain_id))),
93+
faucet_chain_id: Arc::new(Mutex::new(Some(chain_id))),
9494
context: context.clone(),
9595
amount: Amount::from_tokens(1),
96-
max_claims_per_chain: 10,
96+
faucet_init_balance: Amount::from_tokens(10),
9797
end_timestamp: Timestamp::from(6000),
9898
start_timestamp: Timestamp::from(0),
9999
start_balance: Amount::from_tokens(6),

linera-service/tests/linera_net_tests.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,20 +3002,25 @@ async fn test_end_to_end_faucet_chain_limit(config: impl LineraNetConfig) -> Res
30023002
let _guard = INTEGRATION_TEST_GUARD.lock().await;
30033003
tracing::info!("Starting test {}", test_name!());
30043004

3005-
let chain_count = 3;
3005+
let max_claims_per_chain = 3;
30063006

30073007
let (mut net, faucet_client) = config.instantiate().await?;
30083008

30093009
let faucet_chain = faucet_client.load_wallet()?.default_chain().unwrap();
30103010

30113011
let amount = Amount::ONE;
30123012
let mut faucet_service = faucet_client
3013-
.run_faucet(None, faucet_chain, amount, Some(chain_count as u64))
3013+
.run_faucet(
3014+
None,
3015+
faucet_chain,
3016+
amount,
3017+
Some(max_claims_per_chain as u64),
3018+
)
30143019
.await?;
30153020
let faucet = faucet_service.instance();
30163021

30173022
// Create one less chain than the configured limit.
3018-
for _ in 1..chain_count {
3023+
for _ in 1..max_claims_per_chain {
30193024
let client = net.make_client().await;
30203025
let _ = client
30213026
.wallet_init(&[], FaucetOption::NewChain(&faucet))

0 commit comments

Comments
 (0)