ci: docker_tag=dev-test

**Motivations :**
- Corriger l'ordre des opérations : scan complet AVANT demande faucet, puis scan APRÈS réception transaction
- Éviter la course entre le scan et l'arrivée des transactions faucet
- Optimiser la logique de scan pour éviter les scans inutiles

**Modifications :**
- src/services/service.ts: Ajout de ensureCompleteInitialScan() avant getTokensFromFaucet(), flag hasReceivedTransaction pour tracker les transactions, optimisation de waitForAmount() pour scanner seulement après réception de transaction

**Pages affectées :**
- Service de gestion des tokens faucet avec ordre d'opérations optimisé
- Logique de scan conditionnelle basée sur la réception de transactions
This commit is contained in:
NicolasCantu 2025-10-24 01:32:28 +02:00
parent d013676f9f
commit 683743d629

View File

@ -771,6 +771,7 @@ export default class Services {
}
private isScanningBlocks = false;
private hasReceivedTransaction = false; // Track if we've received any transaction
private async safeScanBlocks(): Promise<void> {
if (this.isScanningBlocks) {
@ -818,55 +819,31 @@ export default class Services {
return amount;
}
// Force SDK to scan blocks to update wallet state
if (attempts < 20) { // Don't scan on first attempt
console.log('🔄 Forcing SDK block scan to update wallet state...');
this.updateUserStatus('🔄 Synchronizing wallet with blockchain...');
// Only scan if we've received a transaction (NewTx message)
if (this.hasReceivedTransaction && attempts < 20) {
console.log('🔄 Transaction received, scanning blocks to update wallet state...');
this.updateUserStatus('🔄 Processing received transaction...');
try {
// Get current device to check if we need a complete scan
const device = await this.getDeviceFromDatabase();
if (device && device.sp_wallet) {
console.log('🔍 Device wallet state for faucet scan:', {
birthday: device.sp_wallet.birthday,
last_scan: device.sp_wallet.last_scan,
current_block: this.currentBlockHeight
});
// For faucet tokens, we need to scan from birthday to current block
// even if birthday equals current block (new wallet case)
if (device.sp_wallet.birthday <= this.currentBlockHeight) {
// For new wallets, scan from much earlier to catch faucet transactions
const scanFromHeight = device.sp_wallet.birthday === this.currentBlockHeight
? Math.max(0, this.currentBlockHeight - 100) // Scan from 100 blocks earlier for new wallets
: device.sp_wallet.birthday;
console.log(`🔄 Forcing complete scan from block ${scanFromHeight} to current block ${this.currentBlockHeight}...`);
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
console.log('✅ Complete block scan completed');
} else {
console.log('🔄 Using safe scan blocks...');
await this.safeScanBlocks();
}
} else {
console.log('🔄 Using safe scan blocks (no device found)...');
await this.safeScanBlocks();
}
// Force a complete scan to catch the new transaction
console.log(`🔄 Scanning blocks to catch new transaction...`);
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
console.log('✅ Block scan completed after transaction');
// Check amount again after scanning
const newAmount = this.getAmount();
console.log(`💰 Amount after forced scan: ${newAmount}`);
console.log(`💰 Amount after transaction scan: ${newAmount}`);
if (newAmount > 0) {
this.updateUserStatus(`💰 Found ${newAmount} tokens in wallet!`);
} else {
this.updateUserStatus('⏳ Waiting for tokens to be confirmed on blockchain...');
this.updateUserStatus('⏳ Transaction processed, waiting for confirmation...');
}
} catch (scanError) {
console.error('❌ Error during forced block scan:', scanError);
this.updateUserStatus('⚠️ Blockchain synchronization in progress...');
console.error('❌ Error during transaction scan:', scanError);
this.updateUserStatus('⚠️ Processing transaction...');
}
} else {
this.updateUserStatus('🪙 Requesting tokens from faucet...');
} else if (!this.hasReceivedTransaction) {
this.updateUserStatus('⏳ Waiting for faucet transaction...');
}
attempts--;
@ -989,6 +966,11 @@ export default class Services {
// console.log('members:', this.getAllMembers());
// console.log('relayAddress:', relayAddress, 'feeRate:', feeRate);
// First, ensure we have a complete initial scan before requesting faucet tokens
console.log('🔄 Ensuring complete initial scan before faucet request...');
await this.ensureCompleteInitialScan();
// Now request tokens from faucet
await this.getTokensFromFaucet();
const membersObj = this.getAllMembers();
@ -1206,6 +1188,9 @@ export default class Services {
// Notify user that a transaction was received
this.updateUserStatus('📨 New transaction received from blockchain...');
// Mark that we've received a transaction for waitForAmount
this.hasReceivedTransaction = true;
const membersList = Object.values(this.getAllMembers()).map(member => ({
sp_addresses: member.sp_addresses
}));
@ -1933,6 +1918,37 @@ export default class Services {
console.log(`✅ Block height received: ${this.currentBlockHeight}`);
}
/**
* Ensures a complete initial scan is performed before requesting faucet tokens
* This prevents the race condition between scan and faucet transactions
*/
public async ensureCompleteInitialScan(): Promise<void> {
console.log('🔄 Ensuring complete initial scan...');
try {
const device = await this.getDeviceFromDatabase();
if (!device || !device.sp_wallet) {
throw new Error('Device not found or wallet not initialized');
}
// Force a complete scan from birthday to current block height
const scanFromHeight = Math.max(0, this.currentBlockHeight - 100);
console.log(`🔄 Performing complete scan from block ${scanFromHeight} to ${this.currentBlockHeight}...`);
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
console.log('✅ Complete initial scan completed');
// Update last_scan to current block height
device.sp_wallet.last_scan = this.currentBlockHeight;
await this.saveDeviceInDatabase(device);
console.log('✅ Wallet scan state updated');
} catch (error) {
console.error('❌ Error during complete initial scan:', error);
throw error;
}
}
public async updateDeviceBlockHeight(): Promise<void> {
if (this.currentBlockHeight === -1) {
throw new Error('Current block height not set');