mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 07:21:32 +02:00
fix(lws): import_account uses add_account + /rescan for the modern LWS
The 1.1-alpha LWS dropped the start_height param from add_account (every account starts scanning at the chain TIP) and moved restore to a separate /rescan admin command. The backend's import_account still passed start_height to add_account — a no-op there, so imported/restored wallets never scanned their history (balance read as 0). Rework import_account: register only if the account is new (add_account errors on a duplicate), then lower its scan height to the wallet birthday with a backwards /rescan when that strictly lowers it (honoring rescan's backwards-only invariant). Drop the now-unused start_height from add_account / AddAccountParams. Verified live against a freshly-built wownero-lws 1.1-alpha: registering with a start_height drives the rescan and the historical outputs are found.
This commit is contained in:
+24
-13
@@ -209,35 +209,46 @@ impl LwsClient {
|
||||
/// current height.
|
||||
#[instrument(skip(self, view_key), fields(net = %self.network))]
|
||||
pub async fn register_account(&self, address: &str, view_key: &str) -> Result<(), AppError> {
|
||||
self.admin_add_account(address, view_key, None).await
|
||||
self.admin_add_account(address, view_key).await
|
||||
}
|
||||
|
||||
/// Register + activate an account scanning from a specific `start_height`
|
||||
/// (avoids re-scanning from genesis for an older wallet).
|
||||
#[instrument(skip(self, view_key), fields(net = %self.network))]
|
||||
/// Register an account and scan it from `start_height` (a wallet birthday).
|
||||
///
|
||||
/// The LWS `add_account` starts every account at the chain TIP and ignores
|
||||
/// any supplied start height, so a restore needs an explicit backwards
|
||||
/// rescan. Read the post-add scan height and only rescan when strictly
|
||||
/// lowering it — honoring the `rescan` backwards-only invariant (a rescan to
|
||||
/// `height >= current` is undefined behavior in monero-lws).
|
||||
#[instrument(skip(self, view_key), fields(net = %self.network, start_height))]
|
||||
pub async fn import_account(
|
||||
&self,
|
||||
address: &str,
|
||||
view_key: &str,
|
||||
start_height: u64,
|
||||
) -> Result<(), AppError> {
|
||||
self.admin_add_account(address, view_key, Some(start_height))
|
||||
.await
|
||||
// `add_account` errors on a duplicate, so only register a NEW account;
|
||||
// an existing one keeps its view key. Either way, lower its scan height
|
||||
// to the birthday with a backwards rescan when that strictly lowers it.
|
||||
let current = match self.account_scan_height(address).await? {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
self.admin_add_account(address, view_key).await?;
|
||||
self.account_scan_height(address).await?.unwrap_or(u64::MAX)
|
||||
}
|
||||
};
|
||||
if start_height < current {
|
||||
self.rescan(vec![address.to_string()], start_height).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn admin_add_account(
|
||||
&self,
|
||||
address: &str,
|
||||
view_key: &str,
|
||||
start_height: Option<u64>,
|
||||
) -> Result<(), AppError> {
|
||||
async fn admin_add_account(&self, address: &str, view_key: &str) -> Result<(), AppError> {
|
||||
let url = format!("{}/add_account", self.admin_url);
|
||||
let body = AdminAddAccountRequest {
|
||||
auth: self.admin_key.expose().to_string(),
|
||||
params: AdminAddAccountParams {
|
||||
address: address.to_string(),
|
||||
key: view_key.to_string(),
|
||||
start_height,
|
||||
},
|
||||
};
|
||||
self.post_ok(url, "add_account", &body).await
|
||||
|
||||
@@ -143,8 +143,6 @@ pub(crate) struct AdminAddAccountParams {
|
||||
pub address: String,
|
||||
/// The private view key.
|
||||
pub key: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub start_height: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
||||
Reference in New Issue
Block a user