Skip to content

feat: metrics for real minter balance#185

Draft
maciejdfinity wants to merge 4 commits intomainfrom
maciej-real-balance
Draft

feat: metrics for real minter balance#185
maciejdfinity wants to merge 4 commits intomainfrom
maciej-real-balance

Conversation

@maciejdfinity
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings April 27, 2026 13:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a periodic Solana RPC balance check for the minter’s main account and exports new Prometheus metrics to track the discrepancy between the on-chain (“real”) balance and the minter’s internally tracked balance.

Changes:

  • Add a daily timer task (RefreshRealBalance) that fetches the minter account’s on-chain balance and records the observed discrepancy in state.
  • Add last_balance_discrepancy to State and expose it via metrics (minter_balance_discrepancy_*).
  • Add an RPC helper (get_balance) to query Solana balance via the SOL RPC canister.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
minter/src/state/tests.rs Updates state construction expectations to include last_balance_discrepancy.
minter/src/state/mod.rs Adds discrepancy observation storage/accessors and a new timer TaskType.
minter/src/rpc/mod.rs Adds get_balance RPC wrapper and corresponding error type.
minter/src/metrics.rs Exposes new discrepancy and refresh timestamp gauges.
minter/src/main.rs Registers a new daily timer to run the refresh task.
minter/src/lib.rs Exports the new balance_check module.
minter/src/balance_check.rs Implements the daily refresh task that fetches on-chain balance and records discrepancy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +34
pub async fn refresh_real_balance<R: CanisterRuntime>(runtime: R) {
let _guard = match TimerGuard::new(TaskType::RefreshRealBalance) {
Ok(guard) => guard,
Err(_) => return,
};

let master_key = lazy_get_schnorr_master_key(&runtime).await;
let address = minter_address(&master_key, &runtime);

match get_balance(&runtime, address).await {
Ok(balance) => {
let observed_at = runtime.time();
let diff = mutate_state(|s| {
s.record_balance_discrepancy(balance, observed_at);
s.last_balance_discrepancy()
.expect("BUG: just-recorded discrepancy must be present")
.diff_lamports
});
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior here (daily balance RPC + state update) is currently untested. Please add unit tests covering: (1) successful refresh records last_balance_discrepancy using the runtime timestamp, (2) RPC error leaves last_balance_discrepancy unchanged, and (3) TimerGuard prevents concurrent refreshes.

Copilot uses AI. Check for mistakes.
Comment thread minter/src/rpc/mod.rs
Comment on lines +167 to +175
pub async fn get_balance<R: CanisterRuntime>(
runtime: &R,
address: Address,
) -> Result<Lamport, GetBalanceError> {
let client = read_state(|state| state.sol_rpc_client(runtime.inter_canister_call_runtime()));
let result = client
.get_balance(GetBalanceParams {
pubkey: address.into(),
commitment: Some(CommitmentLevel::Finalized),
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_balance is a new RPC wrapper but minter/src/rpc/tests.rs doesn’t cover it yet (other RPC helpers in this module are tested). Please add tests for the Consistent(Ok), Consistent(Err), and Inconsistent cases to ensure error mapping stays correct.

Copilot uses AI. Check for mistakes.

pub const REFRESH_REAL_BALANCE_DELAY: Duration = Duration::from_secs(24 * 60 * 60);

/// Refresh the cached on-chain balance of the minter's main account.
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refresh_real_balance does not actually cache/store the real on-chain balance; it only records the discrepancy (real_balance - tracked_balance) via record_balance_discrepancy. Either adjust this docstring to describe what is stored, or extend the state to also persist the observed real balance if that’s the intended behavior.

Suggested change
/// Refresh the cached on-chain balance of the minter's main account.
/// Refresh the observed on-chain balance of the minter's main account and
/// record its discrepancy relative to the tracked balance.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 27, 2026 14:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread minter/src/state/mod.rs
Comment on lines +119 to +120
/// changing afterwards. Refreshed once per day by a timer; `None` until
/// the first refresh succeeds.
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc comment says this observation is "Refreshed once per day", but setup_timers also triggers an immediate refresh on install/upgrade. Update the comment to reflect the actual refresh schedule (e.g., initial refresh shortly after install/upgrade, then daily).

Suggested change
/// changing afterwards. Refreshed once per day by a timer; `None` until
/// the first refresh succeeds.
/// changing afterwards. Refreshed shortly after install/upgrade, and then
/// once per day by a timer; `None` until the first refresh succeeds.

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +16
/// Each call makes an RPC request to the Solana network, so this runs at most
/// once per day (see [`REFRESH_REAL_BALANCE_DELAY`]).
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function docs say this runs "at most once per day", but the canister also calls refresh_real_balance immediately on install/upgrade (in addition to the 24h interval). Please adjust the wording to avoid implying a strict daily maximum.

Suggested change
/// Each call makes an RPC request to the Solana network, so this runs at most
/// once per day (see [`REFRESH_REAL_BALANCE_DELAY`]).
/// Each call makes an RPC request to the Solana network, so periodic refreshes
/// are scheduled with a 24-hour delay (see [`REFRESH_REAL_BALANCE_DELAY`]).

Copilot uses AI. Check for mistakes.
Comment thread minter/src/metrics.rs
w.encode_gauge(
"minter_balance_discrepancy_lamports",
discrepancy_lamports,
"Difference (real on-chain balance minus tracked balance) of the minter's main account at the time of the last successful refresh, in lamports. Both sides are sampled together; refreshed once per day. Reports 0 until the first refresh succeeds.",
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metric help text says the discrepancy is "refreshed once per day", but the implementation also refreshes once shortly after install/upgrade. Consider updating the description so dashboards/users understand the extra initial refresh behavior.

Suggested change
"Difference (real on-chain balance minus tracked balance) of the minter's main account at the time of the last successful refresh, in lamports. Both sides are sampled together; refreshed once per day. Reports 0 until the first refresh succeeds.",
"Difference (real on-chain balance minus tracked balance) of the minter's main account at the time of the last successful refresh, in lamports. Both sides are sampled together; refreshed shortly after install/upgrade and then once per day. Reports 0 until the first refresh succeeds.",

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants