What changed, and why it matters
This commit is a routine internal refactor of how the app tracks its Mimblewimble (MWEB) background server. It replaces a map indexed by cryptocurrency network with a map that stores both the server handle and the client handle together, and makes the server interface constructor a compile-time constant. There is no user-facing change and no security fix or vulnerability introduced in the diff.
No security action required. Review as normal code-quality refactor if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors MwebdServerInterface and MwebdService to pass an opaque server handle (OpaqueMwebdServer) instead of using a CryptoCurrencyNetwork-keyed internal map. createAndStartServer now returns a record containing both the server handle and the port; stopServer and getServerStatus accept the opaque handle. The interface class gains a const constructor and the implementation is made const. The previous per-network server map is removed from the implementation, shifting lifecycle ownership to the caller. No cryptographic, network, or permission changes are present.
Changed components
lib/services/mwebd_service.dartlib/wl_gen/interfaces/mwebd_server_interface.darttool/wl_templates/MWEBD_mwebd_server_interface_impl.template.dartInspect captured patch +53 / −31
diff --git a/lib/services/mwebd_service.dart b/lib/services/mwebd_service.dart
index 3c60a9a..2462257 100644
--- a/lib/services/mwebd_service.dart
+++ b/lib/services/mwebd_service.dart
@@ -24,7 +24,11 @@ final class MwebdService {
CryptoCurrencyNetwork.test4 => throw UnimplementedError(),
};
- final Map<CryptoCurrencyNetwork, MwebClient> _map = {};
+ final Map<
+ CryptoCurrencyNetwork,
+ ({OpaqueMwebdServer server, MwebClient client})
+ >
+ _map = {};
late final StreamSubscription<TorConnectionStatusChangedEvent>
_torStatusListener;
@@ -84,16 +88,16 @@ final class MwebdService {
: "socks5://${proxyInfo.host.address}:${proxyInfo.port}";
final nets = _map.keys;
for (final net in nets) {
- final oldClient = _map.remove(net)!;
- await oldClient.cleanup();
- final oldServerInfo = await mwebdServerInterface.stopServer(net);
+ final old = _map.remove(net)!;
+ await old.client.cleanup();
+ final oldServerInfo = await mwebdServerInterface.stopServer(old.server);
final port = await _getRandomUnusedPort();
if (port == null) {
throw Exception("Could not find an unused port for mwebd");
}
- final serverPort = await mwebdServerInterface.createAndStartServer(
+ final serverData = await mwebdServerInterface.createAndStartServer(
net,
chain: oldServerInfo.chain,
dataDir: oldServerInfo.dataDir,
@@ -102,7 +106,9 @@ final class MwebdService {
serverPort: port,
);
- _map[net] = MwebClient.fromHost("127.0.0.1", serverPort);
+ final newClient = MwebClient.fromHost("127.0.0.1", serverData.port);
+
+ _map[net] = (server: serverData.server, client: newClient);
}
});
}
@@ -116,10 +122,10 @@ final class MwebdService {
}
if (_map.isNotEmpty) {
- for (final net in _map.keys) {
+ for (final old in _map.values) {
try {
- await _map[net]?.cleanup();
- await mwebdServerInterface.stopServer(net);
+ await old.client.cleanup();
+ await mwebdServerInterface.stopServer(old.server);
} catch (e, s) {
Logging.instance.i(
"Switching mwebd chain. Error likely expected here.",
@@ -154,7 +160,7 @@ final class MwebdService {
proxy = "";
}
- final serverPort = await mwebdServerInterface.createAndStartServer(
+ final serverData = await mwebdServerInterface.createAndStartServer(
net,
chain: chain,
dataDir: dir.path,
@@ -163,7 +169,9 @@ final class MwebdService {
serverPort: port,
);
- _map[net] = MwebClient.fromHost("127.0.0.1", serverPort);
+ final newClient = MwebClient.fromHost("127.0.0.1", serverData.port);
+
+ _map[net] = (server: serverData.server, client: newClient);
Logging.instance.i("MwebdService init($net) completed!");
});
@@ -172,14 +180,14 @@ final class MwebdService {
/// Get server status. Returns null if no server was initialized.
Future<Status?> getServerStatus(CryptoCurrencyNetwork net) {
return _updateLock.protect(() {
- return mwebdServerInterface.getServerStatus(net);
+ return mwebdServerInterface.getServerStatus(_map[net]?.server);
});
}
/// Get client for network. Returns null if no server was initialized.
Future<MwebClient?> getClient(CryptoCurrencyNetwork net) async {
return await _updateLock.protect(() async {
- return _map[net];
+ return _map[net]?.client;
});
}
diff --git a/lib/wl_gen/interfaces/mwebd_server_interface.dart b/lib/wl_gen/interfaces/mwebd_server_interface.dart
index 08dc08f..8b597d0 100644
--- a/lib/wl_gen/interfaces/mwebd_server_interface.dart
+++ b/lib/wl_gen/interfaces/mwebd_server_interface.dart
@@ -3,7 +3,9 @@ import '../../wallets/crypto_currency/crypto_currency.dart';
export '../generated/mwebd_server_interface_impl.dart';
abstract class MwebdServerInterface {
- Future<int> createAndStartServer(
+ const MwebdServerInterface();
+
+ Future<({OpaqueMwebdServer server, int port})> createAndStartServer(
CryptoCurrencyNetwork net, {
required String chain,
required String dataDir,
@@ -13,10 +15,10 @@ abstract class MwebdServerInterface {
});
Future<({String chain, String dataDir, String peer})> stopServer(
- CryptoCurrencyNetwork net,
+ OpaqueMwebdServer server,
);
- Future<Status?> getServerStatus(CryptoCurrencyNetwork net);
+ Future<Status?> getServerStatus(OpaqueMwebdServer? server);
}
// local copy
@@ -60,3 +62,11 @@ class Status {
blockTime,
);
}
+
+final class OpaqueMwebdServer {
+ final Object _value;
+
+ const OpaqueMwebdServer(this._value);
+
+ T get<T>() => _value as T;
+}
diff --git a/tool/wl_templates/MWEBD_mwebd_server_interface_impl.template.dart b/tool/wl_templates/MWEBD_mwebd_server_interface_impl.template.dart
index bf3793e..55ba2c6 100644
--- a/tool/wl_templates/MWEBD_mwebd_server_interface_impl.template.dart
+++ b/tool/wl_templates/MWEBD_mwebd_server_interface_impl.template.dart
@@ -12,13 +12,17 @@ MwebdServerInterface _getInterface() => throw Exception("MWEBD not enabled!");
//END_OFF
//ON
-MwebdServerInterface _getInterface() => _MwebdServerInterfaceImpl();
+MwebdServerInterface _getInterface() => const _MwebdServerInterfaceImpl();
+
+extension _OpaqueMwebdServerExt on OpaqueMwebdServer {
+ MwebdServer get value => get();
+}
class _MwebdServerInterfaceImpl extends MwebdServerInterface {
- final Map<CryptoCurrencyNetwork, MwebdServer> _map = {};
+ const _MwebdServerInterfaceImpl();
@override
- Future<int> createAndStartServer(
+ Future<({OpaqueMwebdServer server, int port})> createAndStartServer(
CryptoCurrencyNetwork net, {
required String chain,
required String dataDir,
@@ -26,10 +30,6 @@ class _MwebdServerInterfaceImpl extends MwebdServerInterface {
String proxy = "",
required int serverPort,
}) async {
- if (_map[net] != null) {
- throw Exception("Server for $net already exists");
- }
-
final newServer = MwebdServer(
chain: chain,
dataDir: dataDir,
@@ -39,22 +39,26 @@ class _MwebdServerInterfaceImpl extends MwebdServerInterface {
);
await newServer.createServer();
await newServer.startServer();
- _map[net] = newServer;
- return newServer.serverPort;
+ return (server: OpaqueMwebdServer(newServer), port: newServer.serverPort);
}
@override
Future<({String chain, String dataDir, String peer})> stopServer(
- CryptoCurrencyNetwork net,
+ OpaqueMwebdServer server,
) async {
- final server = _map.remove(net);
- await server!.stopServer();
- return (chain: server.chain, dataDir: server.dataDir, peer: server.peer);
+ final actual = server.value;
+ final data = (
+ chain: actual.chain,
+ dataDir: actual.dataDir,
+ peer: actual.peer,
+ );
+ await actual.stopServer();
+ return data;
}
@override
- Future<Status?> getServerStatus(CryptoCurrencyNetwork net) async {
- final status = await _map[net]?.getStatus();
+ Future<Status?> getServerStatus(OpaqueMwebdServer? server) async {
+ final status = await server?.value.getStatus();
if (status == null) return null;
return Status(
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.