Skip to content
Merged

various #1182

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions lib/db/sqlite/firo_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ abstract class _FiroCache {
await StackFileSystem.applicationFiroCacheSQLiteDirectory();

for (final network in networks) {
final sparkSetCacheFile =
File("${sqliteDir.path}/${sparkSetCacheFileName(network)}");
final sparkSetCacheFile = File(
"${sqliteDir.path}/${sparkSetCacheFileName(network)}",
);

final sparkUsedTagsCacheFile =
File("${sqliteDir.path}/${sparkUsedTagsCacheFileName(network)}");
final sparkUsedTagsCacheFile = File(
"${sqliteDir.path}/${sparkUsedTagsCacheFileName(network)}",
);

if (!(await sparkSetCacheFile.exists())) {
await _createSparkSetCacheDb(sparkSetCacheFile.path);
Expand All @@ -91,35 +93,40 @@ abstract class _FiroCache {

static Future<void> _deleteAllCache(CryptoCurrencyNetwork network) async {
final start = DateTime.now();
setCacheDB(network).execute(
"""
setCacheDB(network).execute("""
DELETE FROM SparkSet;
DELETE FROM SparkCoin;
DELETE FROM SparkSetCoins;
VACUUM;
""",
""");
await _deleteUsedTagsCache(network);

Logging.instance.d(
"_deleteAllCache() "
"duration = ${DateTime.now().difference(start)}",
);
usedTagsCacheDB(network).execute(
"""
}

static Future<void> _deleteUsedTagsCache(
CryptoCurrencyNetwork network,
) async {
final start = DateTime.now();

usedTagsCacheDB(network).execute("""
DELETE FROM SparkUsedCoinTags;
VACUUM;
""",
);
""");

Logging.instance.d(
"_deleteAllCache() "
"_deleteUsedTagsCache() "
"duration = ${DateTime.now().difference(start)}",
);
}

static Future<void> _createSparkSetCacheDb(String file) async {
final db = sqlite3.open(
file,
mode: OpenMode.readWriteCreate,
);
final db = sqlite3.open(file, mode: OpenMode.readWriteCreate);

db.execute(
"""
db.execute("""
CREATE TABLE SparkSet (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
blockHash TEXT NOT NULL,
Expand All @@ -145,27 +152,21 @@ abstract class _FiroCache {
FOREIGN KEY (setId) REFERENCES SparkSet(id),
FOREIGN KEY (coinId) REFERENCES SparkCoin(id)
);
""",
);
""");

db.dispose();
}

static Future<void> _createSparkUsedTagsCacheDb(String file) async {
final db = sqlite3.open(
file,
mode: OpenMode.readWriteCreate,
);
final db = sqlite3.open(file, mode: OpenMode.readWriteCreate);

db.execute(
"""
db.execute("""
CREATE TABLE SparkUsedCoinTags (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
tag TEXT NOT NULL UNIQUE,
txid TEXT NOT NULL
);
""",
);
""");

db.dispose();
}
Expand Down
77 changes: 36 additions & 41 deletions lib/db/sqlite/firo_cache_coordinator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ abstract class FiroCacheCoordinator {
}
}

static Future<void> clearSharedCache(CryptoCurrencyNetwork network) async {
static Future<void> clearSharedCache(
CryptoCurrencyNetwork network, {
bool clearOnlyUsedTagsCache = false,
}) async {
if (clearOnlyUsedTagsCache) {
return await _FiroCache._deleteUsedTagsCache(network);
}
return await _FiroCache._deleteAllCache(network);
}

Expand All @@ -38,9 +44,10 @@ abstract class FiroCacheCoordinator {

final setSize =
(await setCacheFile.exists()) ? await setCacheFile.length() : 0;
final tagsSize = (await usedTagsCacheFile.exists())
? await usedTagsCacheFile.length()
: 0;
final tagsSize =
(await usedTagsCacheFile.exists())
? await usedTagsCacheFile.length()
: 0;

Logging.instance.d("Spark cache used tags size: $tagsSize");
Logging.instance.d("Spark cache anon set size: $setSize");
Expand All @@ -67,16 +74,11 @@ abstract class FiroCacheCoordinator {
) async {
await _tagLocks[network]!.protect(() async {
final count = await FiroCacheCoordinator.getUsedCoinTagsCount(network);
final unhashedTags =
await client.getSparkUnhashedUsedCoinsTagsWithTxHashes(
startNumber: count,
);
final unhashedTags = await client
.getSparkUnhashedUsedCoinsTagsWithTxHashes(startNumber: count);
if (unhashedTags.isNotEmpty) {
await _workers[network]!.runTask(
FCTask(
func: FCFuncName._updateSparkUsedTagsWith,
data: unhashedTags,
),
FCTask(func: FCFuncName._updateSparkUsedTagsWith, data: unhashedTags),
);
}
});
Expand All @@ -98,9 +100,7 @@ abstract class FiroCacheCoordinator {

final prevSize = prevMeta?.size ?? 0;

final meta = await client.getSparkAnonymitySetMeta(
coinGroupId: groupId,
);
final meta = await client.getSparkAnonymitySetMeta(coinGroupId: groupId);

progressUpdated?.call(prevSize, meta.size);

Expand Down Expand Up @@ -141,9 +141,10 @@ abstract class FiroCacheCoordinator {
coins.addAll(data);
}

final result = coins
.map((e) => RawSparkCoin.fromRPCResponse(e as List, groupId))
.toList();
final result =
coins
.map((e) => RawSparkCoin.fromRPCResponse(e as List, groupId))
.toList();

await _workers[network]!.runTask(
FCTask(
Expand All @@ -156,20 +157,18 @@ abstract class FiroCacheCoordinator {

// ===========================================================================

static Future<Set<String>> getUsedCoinTags(
static Future<List<String>> getUsedCoinTags(
int startNumber,
CryptoCurrencyNetwork network,
) async {
final result = await _Reader._getSparkUsedCoinTags(
startNumber,
db: _FiroCache.usedTagsCacheDB(network),
);
return result.map((e) => e["tag"] as String).toSet();
return result.map((e) => e["tag"] as String).toList();
}

static Future<int> getUsedCoinTagsCount(
CryptoCurrencyNetwork network,
) async {
static Future<int> getUsedCoinTagsCount(CryptoCurrencyNetwork network) async {
final result = await _Reader._getUsedCoinTagsCount(
db: _FiroCache.usedTagsCacheDB(network),
);
Expand All @@ -195,24 +194,19 @@ abstract class FiroCacheCoordinator {
return [];
}
return result.rows
.map(
(e) => (
tag: e[0] as String,
txid: e[1] as String,
),
)
.map((e) => (tag: e[0] as String, txid: e[1] as String))
.toList();
}

static Future<Set<String>> getUsedCoinTagsFor({
static Future<List<String>> getUsedCoinTagsFor({
required String txid,
required CryptoCurrencyNetwork network,
}) async {
final result = await _Reader._getUsedCoinTagsFor(
txid,
db: _FiroCache.usedTagsCacheDB(network),
);
return result.map((e) => e["tag"] as String).toSet();
return result.map((e) => e["tag"] as String).toList();
}

static Future<bool> checkTagIsUsed(
Expand All @@ -230,16 +224,17 @@ abstract class FiroCacheCoordinator {
String? afterBlockHash,
required CryptoCurrencyNetwork network,
}) async {
final resultSet = afterBlockHash == null
? await _Reader._getSetCoinsForGroupId(
groupId,
db: _FiroCache.setCacheDB(network),
)
: await _Reader._getSetCoinsForGroupIdAndBlockHash(
groupId,
afterBlockHash,
db: _FiroCache.setCacheDB(network),
);
final resultSet =
afterBlockHash == null
? await _Reader._getSetCoinsForGroupId(
groupId,
db: _FiroCache.setCacheDB(network),
)
: await _Reader._getSetCoinsForGroupIdAndBlockHash(
groupId,
afterBlockHash,
db: _FiroCache.setCacheDB(network),
);

return resultSet
.map(
Expand Down
19 changes: 6 additions & 13 deletions lib/db/sqlite/firo_cache_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@ class FCResult {
/// update the sqlite cache
/// Expected json format:
/// returns true if successful, otherwise some exception
FCResult _updateSparkUsedTagsWith(
Database db,
List<List<dynamic>> tags,
) {
FCResult _updateSparkUsedTagsWith(Database db, List<List<dynamic>> tags) {
// hash the tags here since this function is called in a background isolate
final hashedTags = LibSpark.hashTags(
base64Tags: tags.map((e) => e[0] as String).toSet(),
).toList();

final hashedTags =
LibSpark.hashTags(
base64Tags: tags.map((e) => e[0] as String).toList(),
).toList();
if (hashedTags.isEmpty) {
// nothing to add, return early
return FCResult(success: true);
Expand Down Expand Up @@ -70,11 +67,7 @@ FCResult _updateSparkAnonSetCoinsWith(
FROM SparkSet
WHERE blockHash = ? AND setHash = ? AND groupId = ?;
""",
[
meta.blockHash,
meta.setHash,
meta.coinGroupId,
],
[meta.blockHash, meta.setHash, meta.coinGroupId],
);

if (checkResult.isNotEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion lib/electrumx_rpc/electrumx_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ class ElectrumXClient {
"Duration=${DateTime.now().difference(start)}",
);

return tags;
return tags.reversed.toList();
} catch (e, s) {
Logging.instance.e(e, error: e, stackTrace: s);
rethrow;
Expand Down
36 changes: 36 additions & 0 deletions lib/pages/home_view/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import '../../utilities/constants.dart';
import '../../utilities/idle_monitor.dart';
import '../../utilities/prefs.dart';
import '../../utilities/text_styles.dart';
import '../../utilities/util.dart';
import '../../widgets/animated_widgets/rotate_icon.dart';
import '../../widgets/app_icon.dart';
import '../../widgets/background.dart';
Expand Down Expand Up @@ -171,6 +172,41 @@ class _HomeViewState extends ConsumerState<HomeView> {
);
}

Future<void> precacheSettingsIcons(BuildContext context) async {
if (Util.isDesktop) return;

final icons = [
Assets.svg.addressBook,
Assets.svg.downloadFolder,
Assets.svg.lock,
Assets.svg.dollarSign,
Assets.svg.language,
Assets.svg.node,
Assets.svg.arrowRotate,
Assets.svg.arrowUpRight,
Assets.svg.sun,
Assets.svg.circleAlert,
Assets.svg.ellipsis,
Assets.svg.solidSliders,
Assets.svg.questionMessage,
];

for (final asset in icons) {
final loader = SvgAssetLoader(asset);
await svg.cache.putIfAbsent(
loader.cacheKey(context),
() => loader.loadBytes(context),
);
}
}

@override
void didChangeDependencies() {
super.didChangeDependencies();

precacheSettingsIcons(context);
}

@override
void initState() {
_autoLockInfo = ref.read(prefsChangeNotifierProvider).autoLockInfo;
Expand Down
15 changes: 13 additions & 2 deletions lib/pages/spark_names/buy_spark_name_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,22 @@ class _BuySparkNameViewState extends ConsumerState<BuySparkNameView> {
try {
final wallet =
ref.read(pWallets).getWallet(widget.walletId) as SparkInterface;
final myAddress = await wallet.getCurrentReceivingSparkAddress();
Address? myAddress = await wallet.getCurrentReceivingSparkAddress();
if (myAddress == null) {
throw Exception("No spark address found");
}
addressController.text = myAddress.value;

final db = ref.read(pDrift(widget.walletId));
final myNames = await db.select(db.sparkNames).get();
while (myNames.where((e) => e.address == myAddress!.value).isNotEmpty) {
Logging.instance.t(
"Found address that already has a spark name. Generating next address...",
);
myAddress = await wallet.generateNextSparkAddress();
await ref.read(mainDBProvider).updateOrPutAddresses([myAddress]);
}

addressController.text = myAddress!.value;
} catch (e, s) {
Logging.instance.e("_fillCurrentReceiving", error: e, stackTrace: s);
} finally {
Expand Down
Loading
Loading