71 lines
3.2 KiB
Plaintext
71 lines
3.2 KiB
Plaintext
@startuml native_get_consensus
|
||
title Native — ConnectToNatives : fetch pool + Phase 1 + Phase 2
|
||
|
||
participant "Node / Indexer\\n(appelant)" as Caller
|
||
participant "Native A" as NA
|
||
participant "Native B" as NB
|
||
participant "Indexer A\\n(stable voter)" as IA
|
||
|
||
note over Caller: NativeIndexerAddresses configured\\nConnectToNatives() called from ConnectToIndexers
|
||
|
||
== Step 1 : heartbeat to the native mesh (nativeHeartbeatOnce) ==
|
||
Caller -> NA: SendHeartbeat /opencloud/heartbeat/1.0
|
||
Caller -> NB: SendHeartbeat /opencloud/heartbeat/1.0
|
||
|
||
== Step 2 : parrallel fetch pool (timeout 6s) ==
|
||
par fetchIndexersFromNative — parallel
|
||
Caller -> NA: NewStream /opencloud/native/indexers/1.0\\nGetIndexersRequest{Count: maxIndexer, From: PeerID}
|
||
NA -> NA: reachableLiveIndexers()\\ntri par w(F) = fillRate×(1−fillRate) desc
|
||
NA --> Caller: GetIndexersResponse{Indexers:[IA,IB], FillRates:{IA:0.3,IB:0.6}}
|
||
else
|
||
Caller -> NB: NewStream /opencloud/native/indexers/1.0
|
||
NB -> NB: reachableLiveIndexers()
|
||
NB --> Caller: GetIndexersResponse{Indexers:[IA,IB], FillRates:{IA:0.3,IB:0.6}}
|
||
end par
|
||
|
||
note over Caller: Fusion → candidates=[IA,IB]\\nisFallback=false
|
||
|
||
alt isFallback=true (native give themself as Fallback indexer)
|
||
note over Caller: resolvePool : avoid consensus\\nadmittedAt = Now (zero)\\nStaticIndexers = {native_addr}
|
||
else isFallback=false → Phase 1 + Phase 2
|
||
== Phase 1 — clientSideConsensus (timeout 3s/natif, 4s total) ==
|
||
par Parralel Consensus
|
||
Caller -> NA: NewStream /opencloud/native/consensus/1.0\\nConsensusRequest{Candidates:[IA,IB]}
|
||
NA -> NA: compare with clean liveIndexers
|
||
NA --> Caller: ConsensusResponse{Trusted:[IA,IB], Suggestions:[]}
|
||
else
|
||
Caller -> NB: NewStream /opencloud/native/consensus/1.0
|
||
NB --> Caller: ConsensusResponse{Trusted:[IA], Suggestions:[IC]}
|
||
end par
|
||
|
||
note over Caller: IA → 2/2 votes → confirmed ✓\\nIB → 1/2 vote → refusé ✗\\nIC → suggestion → round 2 if confirmed < maxIndexer
|
||
|
||
alt confirmed < maxIndexer && available suggestions
|
||
note over Caller: Round 2 — rechallenge with confirmed + sample(suggestions)\\nclientSideConsensus([IA, IC])
|
||
end
|
||
|
||
note over Caller: admittedAt = time.Now()
|
||
|
||
== Phase 2 — indexerLivenessVote (timeout 3s/votant, 4s total) ==
|
||
note over Caller: Search for stable voters in Subscribed Indexers\\nAdmittedAt != zero && age >= MinStableAge (2min)
|
||
|
||
alt Stable Voters are available
|
||
par Phase 2 parrallel
|
||
Caller -> IA: NewStream /opencloud/indexer/consensus/1.0\\nIndexerConsensusRequest{Candidates:[IA]}
|
||
IA -> IA: StreamRecords[ProtocolHB][candidate]\\ntime.Since(LastSeen) <= 120s && LastScore >= 30.0
|
||
IA --> Caller: IndexerConsensusResponse{Alive:[IA]}
|
||
end par
|
||
note over Caller: alive IA confirmed per quorum > 0.5\\npool = {IA}
|
||
else No voters are stable (startup)
|
||
note over Caller: Phase 1 keep directly\\n(no indexer reaches MinStableAge)
|
||
end
|
||
|
||
== Replacement pool ==
|
||
Caller -> Caller: replaceStaticIndexers(pool, admittedAt)\\nStaticIndexerMeta[IA].AdmittedAt = admittedAt
|
||
end
|
||
|
||
== Étape 3 : heartbeat to indexers pool (ConnectToIndexers) ==
|
||
Caller -> Caller: SendHeartbeat /opencloud/heartbeat/1.0\\nvers StaticIndexers
|
||
|
||
@enduml
|