linera-io/linera-protocol · error
Expected balance: {expected_balance}, actual balance: {actua
Error message
Expected balance: {expected_balance}, actual balance: {actual_balance} What it means
After the benchmark fired all fungible-token transfers, it polls each receiving app's balance with sleeps of 0+1+2+3+4 seconds (~10s total). If the balance never reaches the expected value by the last iteration (i==4), it bails with expected vs actual. This means transfers (or the messages carrying them) did not fully process/converge within the wait window — some transfers failed outright (counted as Failures earlier) or cross-chain messages were still in flight.
Source
Thrown at linera-service/src/benchmark.rs:246
|((_, context, node_service), expected_balances)| {
try_join_all(apps.iter().zip(expected_balances).map(
|((_, sender_context, _), expected_balance)| async move {
if expected_balance == Amount::ZERO {
return Ok(()); // No transfers: The app won't be registered on this chain.
}
node_service.process_inbox(&context.default_chain).await?;
let app = FungibleApp(node_service.make_application(
&context.default_chain,
&sender_context.application_id,
)?);
for i in 0.. {
linera_base::time::timer::sleep(Duration::from_secs(i)).await;
let actual_balance = app.get_amount(&context.owner).await;
if actual_balance == expected_balance {
break;
}
if i == 4 {
bail!(
"Expected balance: {expected_balance}, actual balance: {actual_balance}",
);
}
}
assert_eq!(app.get_amount(&context.owner).await, expected_balance);
Ok(())
},
))
},
))
.await?;
Ok(())
}
struct FungibleApp(ApplicationWrapper<FungibleTokenAbi>);
impl FungibleApp {View on GitHub (pinned to 6c226ddcb3)
Solutions
- Check the 'Successes:/Failures:' lines printed just before: if failures > 0, the mismatch is failed transfers, not slowness — fix why they failed (funding, fees, contention).
- Reduce load (fewer wallets or transactions) so messages settle within the retry window.
- Give the deployment more resources / closer validators to speed up message processing.
- If you intentionally run heavy loads, raise the retry bound (i == 4) / sleep schedule in benchmark.rs before the final check.
Example fix
// before
for i in 0.. {
linera_base::time::timer::sleep(Duration::from_secs(i)).await;
let actual_balance = app.get_amount(&context.owner).await;
if actual_balance == expected_balance { break; }
if i == 4 { bail!("Expected balance: {expected_balance}, actual balance: {actual_balance}"); }
}
// after (heavy-load tuning): wider window and a diagnosed failure
for i in 0..10 {
linera_base::time::timer::sleep(Duration::from_secs(i)).await;
if app.get_amount(&context.owner).await == expected_balance { return Ok(()); }
}
bail!("balances did not converge in 45s; check the Failures count above for dropped transfers"); Defensive patterns
Strategy: retry
Validate before calling
// Before the balance check, confirm transfer success counts:
anyhow::ensure!(failures == 0, "{failures} transfers failed; balances cannot converge"); Try / catch
// The loop is the retry; on final mismatch, surface both balances plus the earlier // Successes/Failures counts so the operator can tell 'slow' from 'lost'.
Prevention
- Tune load to what the deployment can settle within ~10s.
- Fund wallets amply so no transfer fails on balance/fees.
- Treat any non-zero Failures count as the real error; the balance bail is only the symptom.
When it happens
Trigger: Running benchmark_with_fungible where a subset of transfer operations fail (shown in the 'Failures:' log line) or process_inbox/synchronization lag exceeds ~10 seconds under load; then the final assert would also fail. The bail fires first once i reaches 4 with a mismatching balance.
Common situations: Overloaded benchmark nodes (too many wallets/transactions for the machine) causing slow block processing; network latency between the client and validator set; some transfers rejected (insufficient balance for fees) so the expected balance can never be reached.
Related errors
- Failed to unwrap shared context
- owner should be different from spender
- invalid block export configuration: {message}
- Expected an `ExecutionError`. Got: {self:#?}
- Expected an `ExecutionError`. Got: {chain_error:#?}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/55bd76072b45fe03.
Report an issue: GitHub.