Skip to content

Commit a4d30e1

Browse files
Merge pull request #898 from cypherstack/firo_exchange_addresses
Firo exchange addresses and bug fixes
2 parents 68180d0 + d30e724 commit a4d30e1

File tree

48 files changed

+809
-455
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+809
-455
lines changed

lib/db/sqlite/firo_cache.dart

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import '../../electrumx_rpc/electrumx_client.dart';
1212
import '../../utilities/extensions/extensions.dart';
1313
import '../../utilities/logger.dart';
1414
import '../../utilities/stack_file_system.dart';
15+
import '../../wallets/crypto_currency/crypto_currency.dart';
1516

1617
part 'firo_cache_coordinator.dart';
1718
part 'firo_cache_reader.dart';
@@ -31,29 +32,39 @@ void _debugLog(Object? object) {
3132
abstract class _FiroCache {
3233
static const int _setCacheVersion = 1;
3334
static const int _tagsCacheVersion = 2;
34-
static const String sparkSetCacheFileName =
35-
"spark_set_v$_setCacheVersion.sqlite3";
36-
static const String sparkUsedTagsCacheFileName =
37-
"spark_tags_v$_tagsCacheVersion.sqlite3";
38-
39-
static Database? _setCacheDB;
40-
static Database? _usedTagsCacheDB;
41-
static Database get setCacheDB {
42-
if (_setCacheDB == null) {
35+
36+
static final networks = [
37+
CryptoCurrencyNetwork.main,
38+
CryptoCurrencyNetwork.test,
39+
];
40+
41+
static String sparkSetCacheFileName(CryptoCurrencyNetwork network) =>
42+
network == CryptoCurrencyNetwork.main
43+
? "spark_set_v$_setCacheVersion.sqlite3"
44+
: "spark_set_v${_setCacheVersion}_${network.name}.sqlite3";
45+
static String sparkUsedTagsCacheFileName(CryptoCurrencyNetwork network) =>
46+
network == CryptoCurrencyNetwork.main
47+
? "spark_tags_v$_tagsCacheVersion.sqlite3"
48+
: "spark_tags_v${_tagsCacheVersion}_${network.name}.sqlite3";
49+
50+
static final Map<CryptoCurrencyNetwork, Database> _setCacheDB = {};
51+
static final Map<CryptoCurrencyNetwork, Database> _usedTagsCacheDB = {};
52+
static Database setCacheDB(CryptoCurrencyNetwork network) {
53+
if (_setCacheDB[network] == null) {
4354
throw Exception(
4455
"FiroCache.init() must be called before accessing FiroCache.db!",
4556
);
4657
}
47-
return _setCacheDB!;
58+
return _setCacheDB[network]!;
4859
}
4960

50-
static Database get usedTagsCacheDB {
51-
if (_usedTagsCacheDB == null) {
61+
static Database usedTagsCacheDB(CryptoCurrencyNetwork network) {
62+
if (_usedTagsCacheDB[network] == null) {
5263
throw Exception(
5364
"FiroCache.init() must be called before accessing FiroCache.db!",
5465
);
5566
}
56-
return _usedTagsCacheDB!;
67+
return _usedTagsCacheDB[network]!;
5768
}
5869

5970
static Future<void>? _initFuture;
@@ -63,38 +74,42 @@ abstract class _FiroCache {
6374
final sqliteDir =
6475
await StackFileSystem.applicationFiroCacheSQLiteDirectory();
6576

66-
final sparkSetCacheFile = File("${sqliteDir.path}/$sparkSetCacheFileName");
67-
final sparkUsedTagsCacheFile =
68-
File("${sqliteDir.path}/$sparkUsedTagsCacheFileName");
77+
for (final network in networks) {
78+
final sparkSetCacheFile =
79+
File("${sqliteDir.path}/${sparkSetCacheFileName(network)}");
6980

70-
if (!(await sparkSetCacheFile.exists())) {
71-
await _createSparkSetCacheDb(sparkSetCacheFile.path);
72-
}
73-
if (!(await sparkUsedTagsCacheFile.exists())) {
74-
await _createSparkUsedTagsCacheDb(sparkUsedTagsCacheFile.path);
75-
}
81+
final sparkUsedTagsCacheFile =
82+
File("${sqliteDir.path}/${sparkUsedTagsCacheFileName(network)}");
7683

77-
_setCacheDB = sqlite3.open(
78-
sparkSetCacheFile.path,
79-
mode: OpenMode.readWrite,
80-
);
81-
_usedTagsCacheDB = sqlite3.open(
82-
sparkUsedTagsCacheFile.path,
83-
mode: OpenMode.readWrite,
84-
);
84+
if (!(await sparkSetCacheFile.exists())) {
85+
await _createSparkSetCacheDb(sparkSetCacheFile.path);
86+
}
87+
if (!(await sparkUsedTagsCacheFile.exists())) {
88+
await _createSparkUsedTagsCacheDb(sparkUsedTagsCacheFile.path);
89+
}
90+
91+
_setCacheDB[network] = sqlite3.open(
92+
sparkSetCacheFile.path,
93+
mode: OpenMode.readWrite,
94+
);
95+
_usedTagsCacheDB[network] = sqlite3.open(
96+
sparkUsedTagsCacheFile.path,
97+
mode: OpenMode.readWrite,
98+
);
99+
}
85100
}
86101

87-
static Future<void> _deleteAllCache() async {
102+
static Future<void> _deleteAllCache(CryptoCurrencyNetwork network) async {
88103
final start = DateTime.now();
89-
setCacheDB.execute(
104+
setCacheDB(network).execute(
90105
"""
91106
DELETE FROM SparkSet;
92107
DELETE FROM SparkCoin;
93108
DELETE FROM SparkSetCoins;
94109
VACUUM;
95110
""",
96111
);
97-
usedTagsCacheDB.execute(
112+
usedTagsCacheDB(network).execute(
98113
"""
99114
DELETE FROM SparkUsedCoinTags;
100115
VACUUM;

lib/db/sqlite/firo_cache_coordinator.dart

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ typedef LTagPair = ({String tag, String txid});
55
/// Wrapper class for [_FiroCache] as [_FiroCache] should eventually be handled in a
66
/// background isolate and [FiroCacheCoordinator] should manage that isolate
77
abstract class FiroCacheCoordinator {
8-
static _FiroCacheWorker? _worker;
8+
static final Map<CryptoCurrencyNetwork, _FiroCacheWorker> _workers = {};
99

1010
static bool _init = false;
1111
static Future<void> init() async {
@@ -14,20 +14,22 @@ abstract class FiroCacheCoordinator {
1414
}
1515
_init = true;
1616
await _FiroCache.init();
17-
_worker = await _FiroCacheWorker.spawn();
17+
for (final network in _FiroCache.networks) {
18+
_workers[network] = await _FiroCacheWorker.spawn(network);
19+
}
1820
}
1921

20-
static Future<void> clearSharedCache() async {
21-
return await _FiroCache._deleteAllCache();
22+
static Future<void> clearSharedCache(CryptoCurrencyNetwork network) async {
23+
return await _FiroCache._deleteAllCache(network);
2224
}
2325

24-
static Future<String> getSparkCacheSize() async {
26+
static Future<String> getSparkCacheSize(CryptoCurrencyNetwork network) async {
2527
final dir = await StackFileSystem.applicationFiroCacheSQLiteDirectory();
2628
final setCacheFile = File(
27-
"${dir.path}/${_FiroCache.sparkSetCacheFileName}",
29+
"${dir.path}/${_FiroCache.sparkSetCacheFileName(network)}",
2830
);
2931
final usedTagsCacheFile = File(
30-
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName}",
32+
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName(network)}",
3133
);
3234
final int bytes =
3335
((await setCacheFile.exists()) ? await setCacheFile.length() : 0) +
@@ -51,13 +53,14 @@ abstract class FiroCacheCoordinator {
5153

5254
static Future<void> runFetchAndUpdateSparkUsedCoinTags(
5355
ElectrumXClient client,
56+
CryptoCurrencyNetwork network,
5457
) async {
55-
final count = await FiroCacheCoordinator.getUsedCoinTagsCount();
58+
final count = await FiroCacheCoordinator.getUsedCoinTagsCount(network);
5659
final unhashedTags = await client.getSparkUnhashedUsedCoinsTagsWithTxHashes(
5760
startNumber: count,
5861
);
5962
if (unhashedTags.isNotEmpty) {
60-
await _worker!.runTask(
63+
await _workers[network]!.runTask(
6164
FCTask(
6265
func: FCFuncName._updateSparkUsedTagsWith,
6366
data: unhashedTags,
@@ -69,10 +72,12 @@ abstract class FiroCacheCoordinator {
6972
static Future<void> runFetchAndUpdateSparkAnonSetCacheForGroupId(
7073
int groupId,
7174
ElectrumXClient client,
75+
CryptoCurrencyNetwork network,
7276
) async {
7377
final blockhashResult =
7478
await FiroCacheCoordinator.getLatestSetInfoForGroupId(
7579
groupId,
80+
network,
7681
);
7782
final blockHash = blockhashResult?.blockHash ?? "";
7883

@@ -81,7 +86,7 @@ abstract class FiroCacheCoordinator {
8186
startBlockHash: blockHash.toHexReversedFromBase64,
8287
);
8388

84-
await _worker!.runTask(
89+
await _workers[network]!.runTask(
8590
FCTask(
8691
func: FCFuncName._updateSparkAnonSetCoinsWith,
8792
data: (groupId, json),
@@ -91,17 +96,22 @@ abstract class FiroCacheCoordinator {
9196

9297
// ===========================================================================
9398

94-
static Future<Set<String>> getUsedCoinTags(int startNumber) async {
99+
static Future<Set<String>> getUsedCoinTags(
100+
int startNumber,
101+
CryptoCurrencyNetwork network,
102+
) async {
95103
final result = await _Reader._getSparkUsedCoinTags(
96104
startNumber,
97-
db: _FiroCache.usedTagsCacheDB,
105+
db: _FiroCache.usedTagsCacheDB(network),
98106
);
99107
return result.map((e) => e["tag"] as String).toSet();
100108
}
101109

102-
static Future<int> getUsedCoinTagsCount() async {
110+
static Future<int> getUsedCoinTagsCount(
111+
CryptoCurrencyNetwork network,
112+
) async {
103113
final result = await _Reader._getUsedCoinTagsCount(
104-
db: _FiroCache.usedTagsCacheDB,
114+
db: _FiroCache.usedTagsCacheDB(network),
105115
);
106116
if (result.isEmpty) {
107117
return 0;
@@ -111,13 +121,14 @@ abstract class FiroCacheCoordinator {
111121

112122
static Future<List<LTagPair>> getUsedCoinTxidsFor({
113123
required List<String> tags,
124+
required CryptoCurrencyNetwork network,
114125
}) async {
115126
if (tags.isEmpty) {
116127
return [];
117128
}
118129
final result = await _Reader._getUsedCoinTxidsFor(
119130
tags,
120-
db: _FiroCache.usedTagsCacheDB,
131+
db: _FiroCache.usedTagsCacheDB(network),
121132
);
122133

123134
if (result.isEmpty) {
@@ -135,20 +146,22 @@ abstract class FiroCacheCoordinator {
135146

136147
static Future<Set<String>> getUsedCoinTagsFor({
137148
required String txid,
149+
required CryptoCurrencyNetwork network,
138150
}) async {
139151
final result = await _Reader._getUsedCoinTagsFor(
140152
txid,
141-
db: _FiroCache.usedTagsCacheDB,
153+
db: _FiroCache.usedTagsCacheDB(network),
142154
);
143155
return result.map((e) => e["tag"] as String).toSet();
144156
}
145157

146158
static Future<bool> checkTagIsUsed(
147159
String tag,
160+
CryptoCurrencyNetwork network,
148161
) async {
149162
return await _Reader._checkTagIsUsed(
150163
tag,
151-
db: _FiroCache.usedTagsCacheDB,
164+
db: _FiroCache.usedTagsCacheDB(network),
152165
);
153166
}
154167

@@ -161,10 +174,11 @@ abstract class FiroCacheCoordinator {
161174
})>> getSetCoinsForGroupId(
162175
int groupId, {
163176
int? newerThanTimeStamp,
177+
required CryptoCurrencyNetwork network,
164178
}) async {
165179
final resultSet = await _Reader._getSetCoinsForGroupId(
166180
groupId,
167-
db: _FiroCache.setCacheDB,
181+
db: _FiroCache.setCacheDB(network),
168182
newerThanTimeStamp: newerThanTimeStamp,
169183
);
170184
return resultSet
@@ -187,10 +201,11 @@ abstract class FiroCacheCoordinator {
187201
int timestampUTC,
188202
})?> getLatestSetInfoForGroupId(
189203
int groupId,
204+
CryptoCurrencyNetwork network,
190205
) async {
191206
final result = await _Reader._getLatestSetInfoForGroupId(
192207
groupId,
193-
db: _FiroCache.setCacheDB,
208+
db: _FiroCache.setCacheDB(network),
194209
);
195210

196211
if (result.isEmpty) {
@@ -206,10 +221,11 @@ abstract class FiroCacheCoordinator {
206221

207222
static Future<bool> checkSetInfoForGroupIdExists(
208223
int groupId,
224+
CryptoCurrencyNetwork network,
209225
) async {
210226
return await _Reader._checkSetInfoForGroupIdExists(
211227
groupId,
212-
db: _FiroCache.setCacheDB,
228+
db: _FiroCache.setCacheDB(network),
213229
);
214230
}
215231
}

lib/db/sqlite/firo_cache_worker.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ class _FiroCacheWorker {
2525
return await completer.future;
2626
}
2727

28-
static Future<_FiroCacheWorker> spawn() async {
28+
static Future<_FiroCacheWorker> spawn(CryptoCurrencyNetwork network) async {
2929
final dir = await StackFileSystem.applicationFiroCacheSQLiteDirectory();
30-
final setCacheFilePath = "${dir.path}/${_FiroCache.sparkSetCacheFileName}";
30+
final setCacheFilePath =
31+
"${dir.path}/${_FiroCache.sparkSetCacheFileName(network)}";
3132
final usedTagsCacheFilePath =
32-
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName}";
33+
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName(network)}";
3334

3435
final initPort = RawReceivePort();
3536
final connection = Completer<(ReceivePort, SendPort)>.sync();

lib/electrumx_rpc/electrumx_client.dart

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ class ElectrumXClient {
10431043
final start = DateTime.now();
10441044
final response = await request(
10451045
requestID: requestID,
1046-
command: "spark.getmempooltxids",
1046+
command: "spark.getmempoolsparktxids",
10471047
);
10481048

10491049
final txids = List<String>.from(response as List)
@@ -1072,7 +1072,7 @@ class ElectrumXClient {
10721072
final start = DateTime.now();
10731073
final response = await request(
10741074
requestID: requestID,
1075-
command: "spark.getmempooltxs",
1075+
command: "spark.getmempoolsparktxs",
10761076
args: [
10771077
{
10781078
"txids": txids,
@@ -1087,10 +1087,10 @@ class ElectrumXClient {
10871087
(
10881088
txid: entry.key,
10891089
serialContext:
1090-
List<String>.from(entry.value["Serial_context"] as List),
1090+
List<String>.from(entry.value["serial_context"] as List),
10911091
// the space after lTags is required lol
10921092
lTags: List<String>.from(entry.value["lTags "] as List),
1093-
coins: List<String>.from(entry.value["Coins"] as List),
1093+
coins: List<String>.from(entry.value["coins"] as List),
10941094
),
10951095
);
10961096
}
@@ -1142,6 +1142,38 @@ class ElectrumXClient {
11421142
}
11431143
// ===========================================================================
11441144

1145+
Future<bool> isMasterNodeCollateral({
1146+
String? requestID,
1147+
required String txid,
1148+
required int index,
1149+
}) async {
1150+
try {
1151+
final start = DateTime.now();
1152+
final response = await request(
1153+
requestID: requestID,
1154+
command: "blockchain.checkifmncollateral",
1155+
args: [
1156+
txid,
1157+
index.toString(),
1158+
],
1159+
);
1160+
1161+
Logging.instance.log(
1162+
"Finished ElectrumXClient.isMasterNodeCollateral, "
1163+
"response: $response, "
1164+
"Duration=${DateTime.now().difference(start)}",
1165+
level: LogLevel.Info,
1166+
);
1167+
1168+
return response as bool;
1169+
} catch (e) {
1170+
Logging.instance.log(e, level: LogLevel.Error);
1171+
rethrow;
1172+
}
1173+
}
1174+
1175+
// ===========================================================================
1176+
11451177
/// Get the current fee rate.
11461178
///
11471179
/// Returns a map with the kay "rate" that corresponds to the free rate in satoshis

0 commit comments

Comments
 (0)