fix(ecstore): keep multi-pool fresh bootstrap proof

Combining a Fresh format-load proof with None from a peer-formatted pool
was collapsing to no authority, so localhost multi-pool clusters never
wrote pool.bin. Treat None as no opinion. Also stabilize the 4-node
quota and volume-proxy e2e cases.

Co-authored-by: RustFS <hello@rustfs.com>
This commit is contained in:
Cursor Agent
2026-09-04 13:13:51 +00:00
parent ab05d958d8
commit c2c8d016db
4 changed files with 89 additions and 41 deletions
+29 -1
View File
@@ -4407,8 +4407,19 @@ pub(crate) enum PoolMetaBootstrapAuthority {
}
impl PoolMetaBootstrapAuthority {
/// Merge per-pool format-load proofs into one cluster bootstrap proof.
///
/// `None` means this pool did not prove bootstrap itself: it loaded an
/// already-written `format.json`, usually formatted by that pool's first-disk
/// peer. That must not cancel a `Fresh` or `LegacyAdoption` proof from another
/// pool. Two different proven authorities still collapse to `None`.
pub(crate) fn combine_across_pools(self, other: Self) -> Self {
if self == other { self } else { Self::None }
match (self, other) {
(Self::None, proven) | (proven, Self::None) => proven,
(Self::Fresh, Self::Fresh) => Self::Fresh,
(Self::LegacyAdoption, Self::LegacyAdoption) => Self::LegacyAdoption,
(Self::Fresh, Self::LegacyAdoption) | (Self::LegacyAdoption, Self::Fresh) => Self::None,
}
}
fn is_proven(self) -> bool {
@@ -4416,6 +4427,23 @@ impl PoolMetaBootstrapAuthority {
}
}
#[cfg(test)]
mod bootstrap_authority_combine_tests {
use super::PoolMetaBootstrapAuthority::*;
#[test]
fn none_does_not_cancel_a_proven_pool() {
assert_eq!(Fresh.combine_across_pools(None), Fresh);
assert_eq!(None.combine_across_pools(Fresh), Fresh);
assert_eq!(LegacyAdoption.combine_across_pools(None), LegacyAdoption);
assert_eq!(None.combine_across_pools(LegacyAdoption), LegacyAdoption);
assert_eq!(Fresh.combine_across_pools(Fresh), Fresh);
assert_eq!(None.combine_across_pools(None), None);
assert_eq!(Fresh.combine_across_pools(LegacyAdoption), None);
assert_eq!(LegacyAdoption.combine_across_pools(Fresh), None);
}
}
impl PoolMetaWriteState {
#[cfg(test)]
pub(crate) fn for_startup(cluster_id: uuid::Uuid, fresh_bootstrap_proven: bool) -> Self {