Skip to content

Commit 163ae41

Browse files
Merge pull request #473 from m1sterc001guy/version_update
feat: update versions in connection stream
2 parents 7dec33f + 447c71c commit 163ae41

11 files changed

Lines changed: 79 additions & 32 deletions

File tree

lib/app.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ class _MyAppState extends State<MyApp> {
564564
fed: _selectedFederation!,
565565
welcomeMessage: meta.welcome,
566566
imageUrl: meta.picture,
567-
guardians: meta.guardians,
568567
onLeaveFederation: _leaveFederation,
569568
),
570569
),

lib/discover.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ class _Discover extends State<Discover> with SingleTickerProviderStateMixin {
7575
inviteCode: inviteCode,
7676
welcomeMessage: meta.welcome,
7777
imageUrl: meta.picture,
78-
guardians: meta.guardians,
7978
joinable: true,
8079
onLeaveFederation: () {},
8180
),

lib/frb_generated.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13058,14 +13058,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
1305813058
PeerStatus dco_decode_peer_status(dynamic raw) {
1305913059
// Codec=Dco (DartCObject based), see doc to use other codecs
1306013060
final arr = raw as List<dynamic>;
13061-
if (arr.length != 5)
13062-
throw Exception('unexpected arr length: expect 5 but see ${arr.length}');
13061+
if (arr.length != 6)
13062+
throw Exception('unexpected arr length: expect 6 but see ${arr.length}');
1306313063
return PeerStatus(
1306413064
peerId: dco_decode_u_16(arr[0]),
1306513065
name: dco_decode_String(arr[1]),
1306613066
online: dco_decode_bool(arr[2]),
1306713067
connectivity: dco_decode_peer_connectivity(arr[3]),
1306813068
url: dco_decode_String(arr[4]),
13069+
version: dco_decode_opt_String(arr[5]),
1306913070
);
1307013071
}
1307113072

@@ -15935,12 +15936,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
1593515936
var var_online = sse_decode_bool(deserializer);
1593615937
var var_connectivity = sse_decode_peer_connectivity(deserializer);
1593715938
var var_url = sse_decode_String(deserializer);
15939+
var var_version = sse_decode_opt_String(deserializer);
1593815940
return PeerStatus(
1593915941
peerId: var_peerId,
1594015942
name: var_name,
1594115943
online: var_online,
1594215944
connectivity: var_connectivity,
1594315945
url: var_url,
15946+
version: var_version,
1594415947
);
1594515948
}
1594615949

@@ -18836,6 +18839,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
1883618839
sse_encode_bool(self.online, serializer);
1883718840
sse_encode_peer_connectivity(self.connectivity, serializer);
1883818841
sse_encode_String(self.url, serializer);
18842+
sse_encode_opt_String(self.version, serializer);
1883918843
}
1884018844

1884118845
@protected

lib/multimint.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -876,12 +876,18 @@ class PeerStatus {
876876
final PeerConnectivity connectivity;
877877
final String url;
878878

879+
/// Guardian's reported `fedimintd` version. Travels with the peer status so
880+
/// the UI reflects guardian upgrades in real time (a guardian upgrade
881+
/// restarts fedimintd, which surfaces as a reconnect on the status stream).
882+
final String? version;
883+
879884
const PeerStatus({
880885
required this.peerId,
881886
required this.name,
882887
required this.online,
883888
required this.connectivity,
884889
required this.url,
890+
this.version,
885891
});
886892

887893
@override
@@ -890,7 +896,8 @@ class PeerStatus {
890896
name.hashCode ^
891897
online.hashCode ^
892898
connectivity.hashCode ^
893-
url.hashCode;
899+
url.hashCode ^
900+
version.hashCode;
894901

895902
@override
896903
bool operator ==(Object other) =>
@@ -901,7 +908,8 @@ class PeerStatus {
901908
name == other.name &&
902909
online == other.online &&
903910
connectivity == other.connectivity &&
904-
url == other.url;
911+
url == other.url &&
912+
version == other.version;
905913
}
906914

907915
/// Fee parameters for an on-chain deposit (peg-in). We can't quote an exact

lib/scan.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,6 @@ class _ScanQRPageState extends State<ScanQRPage> {
358358
inviteCode: field0,
359359
welcomeMessage: meta.welcome,
360360
imageUrl: meta.picture,
361-
guardians: meta.guardians,
362361
joinable: true,
363362
onLeaveFederation: () {},
364363
),
@@ -511,7 +510,6 @@ class _ScanQRPageState extends State<ScanQRPage> {
511510
inviteCode: field0,
512511
welcomeMessage: meta.welcome,
513512
imageUrl: meta.picture,
514-
guardians: meta.guardians,
515513
joinable: true,
516514
ecash: field1,
517515
onLeaveFederation: () {},

lib/screens/federation_info_screen.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class FederationInfoScreen extends StatefulWidget {
1717
final FederationSelector fed;
1818
final String? welcomeMessage;
1919
final String? imageUrl;
20-
final List<Guardian>? guardians;
2120
final VoidCallback onLeaveFederation;
2221

2322
// Joinable mode fields
@@ -30,7 +29,6 @@ class FederationInfoScreen extends StatefulWidget {
3029
required this.fed,
3130
this.welcomeMessage,
3231
this.imageUrl,
33-
this.guardians,
3432
required this.onLeaveFederation,
3533
this.joinable = false,
3634
this.inviteCode,
@@ -472,9 +470,7 @@ class _FederationInfoScreenState extends State<FederationInfoScreen> {
472470
crossAxisAlignment: CrossAxisAlignment.start,
473471
children: [
474472
Text(
475-
context.l10n.versionLabel(
476-
widget.guardians?[index].version ?? '',
477-
),
473+
context.l10n.versionLabel(peer.version ?? ''),
478474
style: theme.textTheme.bodySmall?.copyWith(
479475
color: Colors.grey,
480476
),

lib/screens/my_wallet_screen.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ class _MyWalletScreenState extends State<MyWalletScreen> {
164164
fed: widget.fed,
165165
welcomeMessage: _federationMeta?.welcome,
166166
imageUrl: _federationMeta?.picture,
167-
guardians: _federationMeta?.guardians ?? [],
168167
onLeaveFederation: widget.onLeaveFederation ?? () {},
169168
),
170169
),

lib/sidebar.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ class FederationListItem extends StatelessWidget {
468468
fed: fed,
469469
welcomeMessage: data.welcomeMessage,
470470
imageUrl: data.federationImageUrl,
471-
guardians: data.guardians,
472471
onLeaveFederation: onLeaveFederation,
473472
),
474473
),

rust/ecashapp/src/frb_generated.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15415,12 +15415,14 @@ impl SseDecode for crate::multimint::PeerStatus {
1541515415
let mut var_online = <bool>::sse_decode(deserializer);
1541615416
let mut var_connectivity = <crate::multimint::PeerConnectivity>::sse_decode(deserializer);
1541715417
let mut var_url = <String>::sse_decode(deserializer);
15418+
let mut var_version = <Option<String>>::sse_decode(deserializer);
1541815419
return crate::multimint::PeerStatus {
1541915420
peer_id: var_peerId,
1542015421
name: var_name,
1542115422
online: var_online,
1542215423
connectivity: var_connectivity,
1542315424
url: var_url,
15425+
version: var_version,
1542415426
};
1542515427
}
1542615428
}
@@ -18080,6 +18082,7 @@ impl flutter_rust_bridge::IntoDart for crate::multimint::PeerStatus {
1808018082
self.online.into_into_dart().into_dart(),
1808118083
self.connectivity.into_into_dart().into_dart(),
1808218084
self.url.into_into_dart().into_dart(),
18085+
self.version.into_into_dart().into_dart(),
1808318086
]
1808418087
.into_dart()
1808518088
}
@@ -19980,6 +19983,7 @@ impl SseEncode for crate::multimint::PeerStatus {
1998019983
<bool>::sse_encode(self.online, serializer);
1998119984
<crate::multimint::PeerConnectivity>::sse_encode(self.connectivity, serializer);
1998219985
<String>::sse_encode(self.url, serializer);
19986+
<Option<String>>::sse_encode(self.version, serializer);
1998319987
}
1998419988
}
1998519989

rust/ecashapp/src/multimint.rs

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ pub struct PeerStatus {
310310
pub online: bool,
311311
pub connectivity: PeerConnectivity,
312312
pub url: String,
313+
/// Guardian's reported `fedimintd` version. Travels with the peer status so
314+
/// the UI reflects guardian upgrades in real time (a guardian upgrade
315+
/// restarts fedimintd, which surfaces as a reconnect on the status stream).
316+
pub version: Option<String>,
313317
}
314318

315319
#[derive(Debug, Serialize, Clone)]
@@ -1510,19 +1514,17 @@ impl Multimint {
15101514
futures_util::future::join_all(peers.iter().map(|(peer_id, (name, url))| {
15111515
let client = client.clone();
15121516
async move {
1513-
let online = client
1514-
.api()
1515-
.fedimintd_version((*peer_id).into())
1516-
.await
1517-
.is_ok();
1517+
let fetched_version =
1518+
client.api().fedimintd_version((*peer_id).into()).await.ok();
15181519
PeerStatus {
15191520
peer_id: *peer_id,
15201521
name: name.clone(),
1521-
online,
1522+
online: fetched_version.is_some(),
15221523
// The preview path calls fedimintd_version directly rather than
15231524
// going through the pooled connection, so the hop is always direct.
15241525
connectivity: PeerConnectivity::Direct,
15251526
url: url.clone(),
1527+
version: fetched_version,
15261528
}
15271529
}
15281530
}))
@@ -1534,28 +1536,67 @@ impl Multimint {
15341536
// Get the connection status stream from the client
15351537
let status_stream = client.api().connection_status_stream();
15361538

1537-
let mapped_stream = status_stream.map(move |status_map| {
1538-
let peers_status: Vec<PeerStatus> = peers
1539-
.iter()
1540-
.map(|(peer_id, (name, url))| {
1539+
// Fold the guardian version into each peer status so the UI reflects
1540+
// upgrades in real time without a separate timer. The version only needs
1541+
// (re)fetching when a peer comes online: a guardian upgrade restarts
1542+
// fedimintd, which surfaces here as an offline->online transition. We
1543+
// cache the last-known version per peer and refetch only on that
1544+
// transition (or if we never managed to fetch it) to avoid hitting every
1545+
// guardian on each unrelated connectivity change.
1546+
let mapped_stream = stream::unfold(
1547+
(
1548+
Box::pin(status_stream),
1549+
client,
1550+
peers,
1551+
BTreeMap::<u16, Option<String>>::new(),
1552+
BTreeMap::<u16, bool>::new(),
1553+
),
1554+
|(mut status_stream, client, peers, mut cached_versions, mut prev_online)| async move {
1555+
let status_map = status_stream.next().await?;
1556+
1557+
let mut peers_status = Vec::with_capacity(peers.len());
1558+
for (peer_id, (name, url)) in peers.iter() {
15411559
let (online, connectivity) = match status_map.get(&(*peer_id).into()) {
15421560
Some(FedimintPeerStatus::Connected(c)) => (true, (*c).into()),
15431561
Some(FedimintPeerStatus::Disconnected) | None => {
15441562
(false, PeerConnectivity::Unknown)
15451563
}
15461564
};
1547-
PeerStatus {
1565+
1566+
let version = if online {
1567+
let was_online = prev_online.get(peer_id).copied().unwrap_or(false);
1568+
let have_version =
1569+
cached_versions.get(peer_id).is_some_and(|v| v.is_some());
1570+
if was_online && have_version {
1571+
cached_versions.get(peer_id).cloned().flatten()
1572+
} else {
1573+
let fetched =
1574+
client.api().fedimintd_version((*peer_id).into()).await.ok();
1575+
cached_versions.insert(*peer_id, fetched.clone());
1576+
fetched
1577+
}
1578+
} else {
1579+
None
1580+
};
1581+
1582+
prev_online.insert(*peer_id, online);
1583+
1584+
peers_status.push(PeerStatus {
15481585
peer_id: *peer_id,
15491586
name: name.clone(),
15501587
online,
15511588
connectivity,
15521589
url: url.clone(),
1553-
}
1554-
})
1555-
.collect();
1590+
version,
1591+
});
1592+
}
15561593

1557-
peers_status
1558-
});
1594+
Some((
1595+
peers_status,
1596+
(status_stream, client, peers, cached_versions, prev_online),
1597+
))
1598+
},
1599+
);
15591600

15601601
Ok(mapped_stream.boxed())
15611602
}

0 commit comments

Comments
 (0)