Abstract 1 Introduction 2 Related Work 3 Computing Model and Problem Formalization 4 Tight Solvability Conditions for Binary-Output Tasks 5 Necessity: Impossibility Proofs 6 Sufficiency: Implementing Algorithms 7 Conclusion References Appendix A Sufficiency: Additional Algorithms and Proofs

Tight Conditions for Binary-Output Tasks
Under Crashes

Timothé Albouy ORCID IMDEA Software Institute, Madrid, Spain Antonio Fernández Anta ORCID IMDEA Software Institute, Madrid, Spain
IMDEA Networks Institute, Madrid, Spain
Chryssis Georgiou ORCID University of Cyprus, Nicosia, Cyprus Nicolas Nicolaou ORCID Algolysis Ltd, Nicosia, Cyprus Junlang Wang ORCID IMDEA Networks Institute, Madrid, Spain
Universidad Carlos III de Madrid, Spain
Abstract

This paper explores necessary and sufficient system conditions to solve distributed tasks with binary outputs (i.e., tasks with output values in {0,1}). We focus on the distinct output sets of values a task can produce (intentionally disregarding validity and value multiplicity), considering that some processes may output no value. In a distributed system with n processes, of which up to tn can crash, we provide a complete characterization of the tight conditions on n and t under which every class of tasks with binary outputs is solvable, for both synchronous and asynchronous systems. This output-set approach yields highly general results: it unifies multiple distributed computing problems, such as binary consensus and symmetry breaking, and it produces impossibility proofs that hold for stronger task formulations, including those that consider validity, account for value multiplicity, or move beyond binary outputs.

Keywords and phrases:
Distributed solvability, Asynchrony, Synchrony, Impossibility proofs, Binary-output tasks, Crash tolerance, Disagreement
Copyright and License:
[Uncaptioned image] © Timothé Albouy, Antonio Fernández Anta, Chryssis Georgiou, Nicolas Nicolaou, and Junlang Wang; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Theory of computation Distributed algorithms
Funding:
This work has been partially supported by the Spanish Ministry of Science and Innovation under grants SocialProbing (TED2021-131264B-I00) and DRONAC (PID2022-140560OB-I00), the ERDF “A way of making Europe”, NextGenerationEU, and the Spanish Government’s “Plan de Recuperación, Transformación y Resiliencia”. This work is part of the grant CEX2024-001471-M funded by MICIU/AEI/10.13039/501100011033.
Editors:
Andrei Arusoaie, Emanuel Onica, Michael Spear, and Sara Tucci-Piergiovanni

1 Introduction

Distributed computing examines a wide range of coordination problems involving multiple processes interacting through a communication medium, such as a message-passing network or a shared memory. Many of these problems can be abstracted as distributed tasks, which can be seen as black boxes taking an input vector and producing an output vector. In these vectors, each process has (at most) one private input and one private output value. For example, the well-known consensus problem can be represented as a task with one input value per process (the proposals) and one output value per process (the decisions). In addition to this input/output interface, a task definition can also impose requirements on the following aspects:

  • Input constraint: a constraint on the set of possible input vectors (which is especially relevant for colored tasks [15] and asymmetric problems, e.g., reliable broadcast [6]);

  • Output constraint: a constraint on the set of possible output vectors (e.g., in consensus, all processes decide the same value);

  • Validity: connection between the inputs and outputs (e.g., in consensus, the decided value must have been previously proposed by some process).

A central challenge in this field is to characterize the necessary and sufficient conditions under which distributed tasks can be solved, with many possible variations based on different assumptions on timing (asynchrony, synchrony) or failures (crashes, Byzantine faults, omissions). The celebrated FLP theorem exemplifies this approach by demonstrating that consensus is impossible in any asynchronous system with even one process crash [12].

Towards a unifying framework for task solvability.

When exploring the boundary between solvable and unsolvable tasks in distributed computing, a strategic approach is to analyze the weakest, most general possible version of a task for which an impossibility result still holds. An impossibility proof for a weak task is particularly powerful because it automatically applies to all stronger versions of that same task.

Much of the literature on distributed computability has focused on particular tasks, such as consensus [12], renaming [8], set agreement [9], or election [19]. These studies have established powerful solvability and impossibility results, but they often rely on model-specific arguments (e.g., on the communication medium) or on constraints such as validity, which tie output to input values. This fragmentation makes it difficult to see the common computational structure underlying different tasks. A natural question, therefore, is whether there exists a unifying perspective that abstracts away from inputs and instead focuses on the essential combinatorial structure of task outputs.

Our approach.

In this paper, we address this question for the case of binary-output tasks (i.e., whose output values belong to {0,1}) in crash-prone systems. We introduce a classification based only on the sets of distinct output values that executions of a binary-output task T may produce, disregarding multiplicity in the output values. More formally, we say that a single execution of T produces an output set included in {0,1}, considering that some processes may output no value (possibly intentionally). There are only four possible binary output sets produced by an execution of T: , {0}, {1}, and {0,1}. Hence, the set of output sets of T is defined as the set O{,{0},{1},{0,1}} of all possible output sets that can be produced across all the executions of T (by providing all possible inputs).

This very weak abstraction allows us to strip tasks down to their minimally observable outcomes and ask: given the system size n and crash tolerance t, which sets of output sets are achievable? Or, conversely, given a set of output sets O, which combinations of n and t make O achievable? Our main result is a complete characterization of the tight conditions on n and t that determine solvability for all possible sets of output sets O, both in synchronous and asynchronous models.

The fact that our framework abstracts away the inputs and only focuses on the output sets of binary-output tasks, implies that impossibility proofs established are directly applicable to a broader range of stronger, more constrained tasks, including validity-based and multi-valued tasks. This shift in focus does not just simplify the analysis; it also allows for the generalization of fundamental necessary conditions that apply to stronger task formulations. Moreover, our framework remains expressive enough to capture a wide array of tasks, from classic ones like binary consensus to novel ones such as a new form of symmetry breaking.

It is important to note that, while our approach excels at generalizing impossibility results, the specific system conditions on n and t we identify in this paper are guaranteed to be tight only for binary-output tasks without validity restrictions. Any additional constraint, such as a validity condition or a requirement on value multiplicity, may necessitate a stronger condition on the system parameters to achieve solvability.

Contributions and roadmap.

Our main contributions are the following.

  1. 1.

    A novel framework for studying binary-output tasks: We introduce a new methodology striving to unify all distributed tasks with binary output values. More precisely, we focus on the sets of distinct output bits that can be produced by these tasks in crash-prone environments, abstracting away the input values, the output multiplicity, or the communication medium (message passing or shared memory). As a result, the formalization that we obtain (see Section 3) is quite simple (it only relies on combinatorial techniques), thus facilitating formal reasoning, while staying expressive enough to capture many significant families of distributed tasks.

  2. 2.

    A complete solvability characterization: We exhaustively examine all 16 possible combinations of distinct output bits that binary-output tasks can produce, and we provide the tight conditions to implement each of them (see Section 4, Table 2), both in the asynchronous and synchronous cases, by proving both their necessity (see Section 5), via impossibility proofs, and their sufficiency (see Section 6), via algorithms and correctness proofs.

  3. 3.

    New symmetry-breaking problems: As an interesting twist, our novel way to classify binary-output tasks allowed us to discover new interesting problems, in particular, one that we baptized disagreement (different from classical weak/strong symmetry breaking), which must always guarantee that the system does not agree on one single output value (see Section 6).

Section 2 exposes the research landscape in which this work is situated, and concluding remarks are provided in Section 7. For the sake of presentation clarity, Appendix A contains omitted algorithms and proofs.

2 Related Work

Our work strives to classify and characterize many classes of distributed tasks. In this section, we first present the tasks that are relevant to our characterization (along with some of their most salient (un)solvability results), and we then review the existing endeavors attempting to unify entire families of tasks under the same framework.

The two most studied (non-distinct) families of distributed tasks are agreement and symmetry breaking. Informally, in agreement, we want to constrain the maximum number of different outputs, while in symmetry breaking we want to do the opposite, i.e., constrain the minimum number of different outputs.

Agreement.

The agreement family includes tasks such as k-set agreement [9], reliable broadcast [6], or consensus [20]. In particular, consensus is a fundamental agreement abstraction of distributed computing, where all participants propose a value and must eventually agree on one of the proposed values. A foundational impossibility result for this problem is the FLP theorem [12], which shows that consensus is impossible in an asynchronous system with even one process crash. In this context, Mostéfaoui, Rajsbaum, and Raynal explored how conditions on the input vector can make consensus solvable in asynchronous crash-prone systems [21]. In a way, we take the opposite approach: instead of characterizing the solvability of a task based on its input, we focus on its output (yielding necessary conditions that also hold if we account for inputs). Aside from the asynchronous case, some other works also study the solvability of agreement tasks in synchronous systems [22, 24].

Symmetry breaking.

The symmetry-breaking family includes tasks such as election [17, 25], renaming [8], and weak/strong symmetry breaking (WSB/SSB) [17]. In an election, only one process outputs 1, while all others output 0. In k-renaming, k processes in the system output distinct values (corresponding to their new identities). Notice that our binary-output approach maps to 2-renaming, but not >2-renaming. WSB guarantees that 0 and 1 are output only if all processes are correct, and SSB adds the property that 1 is always output (even if there are faults). Some solvability results also exist for symmetry breaking, e.g., on the wait-free solvability of WSB and renaming [23].

Unification attempts.

Several endeavors before us have attempted to unify multiple classes of distributed tasks under the same framework, in order to draw general results from their common structure. For instance, generalized symmetry breaking (GSB) aims to unify many symmetry-breaking tasks [7, 17], such as election, renaming, and weak symmetry-breaking. Furthermore, many works employ a topological approach to study the computability of distributed tasks. With topology, tasks are modeled as input and output complexes, and solvability is characterized by the existence of continuous maps, with impossibility linked to invariants such as connectivity. One of the most prominent results in this area is the asynchronous computability theorem (ACT), which characterizes the solvability of wait-free tasks in an asynchronous shared-memory model [16]. The musical benches problem also leverages topological techniques to capture 2-set agreement and 2-renaming under the same abstraction in a wait-free shared-memory context [13]. For more material on the applications of combinatorial topology to distributed computing, we refer the interested reader to Herlihy, Kozlov, and Rajsbaum’s monograph [15].

3 Computing Model and Problem Formalization

For clarity, we provide in Table 1 a list of concepts and notations used in this paper.

Table 1: Concepts and notations used in this paper.
Concept or notation Meaning
pi process of the system with identity i
P Set of processes in the system
n Number of processes in the system (0n=|P|)
t Upper bound on the number of crashed processes (0tn)
f Effective number of crashed processes in a run (0ft)
σ{Sync,Async} Timing model (synchronous or asynchronous)
PRNG Pseudo-random number generation
𝗉𝗌𝖾𝗎𝖽𝗈_𝗋𝖺𝗇𝖽𝗈𝗆_𝗉𝗂𝖼𝗄(S) Function returning a pseudo-random value v from set S
T,A,E Task, algorithm, execution
Vin(𝕀{})n Input vector
Vout(𝕆{})n Output vector, with 𝕆={0,1}
Sentinel value denoting no input/output
Unspecified value
𝑛𝑜_𝑜𝑢𝑡 Boolean indicating if is a possible output set or not

3.1 Computing Model

Process model.

We consider a distributed system with a set P={p1,p2,,pn} of processes (|P|=n). Processes are deterministic computing entities that take steps according to their local state and the events they observe, following an algorithm A. Failures are restricted to crash faults: in an execution of the system a process may halt prematurely and take no further steps, but it does not deviate from its algorithm before crashing. We assume an upper bound t on the number of processes that may crash in an execution, with 0tn. A process that does not crash in an execution E is said to be correct in E.

Communication model.

Processes interact through a generic communication medium. This medium is reliable as far as it does not suppress, duplicate, or corrupt information. Every process pP has access to two abstract operations that capture the behavior of this communication medium:

  • 𝖼𝗈𝗆𝗆𝗎𝗇𝗂𝖼𝖺𝗍𝖾 I: process p disseminates some information I to the system processes;

  • 𝗈𝖻𝗌𝖾𝗋𝗏𝖾 I (callback event): process p is notified that information I was communicated.

The length of the information I is not bounded. From a terminology point of view, we say that processes communicate and observe information. The medium guarantees that all correct processes eventually obtain a consistent view of the set of communicated information, while crashed processes may only have partial but always valid views. More formally, the communication abstraction satisfies the following properties (the “C” prefix stands for “communication”).

  • C-Validity: If a process p observes information I, then I must have been previously communicated by some process p.

  • C-Local-Termination: If a correct process p communicates information I, then some correct process p (if there is any) eventually observes I.

  • C-Global-Termination: If a process p observes information I, then all correct processes eventually observe I.

C-Validity is a safety property, while C-Local-Termination and C-Global-Termination are liveness properties. These 𝖼𝗈𝗆𝗆𝗎𝗇𝗂𝖼𝖺𝗍𝖾/𝗈𝖻𝗌𝖾𝗋𝗏𝖾 operations can be implemented straightforwardly on top of classic communication media such as message-passing networks or shared memory, regardless of the number of crashes t or the timing assumptions (synchronous, asynchronous, etc.). For instance, in message passing, they can be realized using reliable broadcast [14] (implementable under synchrony and asynchrony with any tn), which ensures consistency of observations. They can also be implemented from weak shared memory models, such as eventually consistent registers [26]: each process writes its communicated information into a new register, while other processes periodically scan all registers to detect new observable information.

Timing models: Async and Sync.

As usual, we assume the existence of a global clock, to which processes have no access. We consider two classical timing models: asynchrony and synchrony, respectively denoted Async and Sync. For simplicity, we assume in both models that local computation occurs instantaneously, while only communication takes time.

In Async, the speed of information propagation is arbitrary but positive: if a correct process communicates some information I, then all correct processes eventually observe I, but the delay before the observation may be unbounded.

In Sync, communication and process execution proceed in globally coordinated lock-step rounds. Each round consists of two steps: first, a communication step, where processes communicate and observe information, and a computation step, where processes can perform actions such as outputting values [22]. Importantly, all information communicated during the communication step of a round is observed in that step, before the computation step of the same round begins. Therefore, in the Sync model, the communication medium provides the following additional liveness property.

  • C-Synchrony: If an arbitrary process p communicates some information I at the start of synchronous round R, then all processes that observe I do so during the communication step of round R.

Pseudo-randomness.

The algorithms presented in this paper rely on pseudo-random number generation (PRNG). Importantly, the use of PRNG does not strengthen the computing model: PRNG can be implemented deterministically given a local seed, which can, for instance, be derived from the local time of processes [18, p. 184]. The correctness of our algorithms requires that the generated numbers are different across all executions (a perfectly uniform PRNG distribution is not necessary). For that, it is enough that local seeds sometimes change from one execution to another. In the algorithms of this paper, we rely on the 𝗉𝗌𝖾𝗎𝖽𝗈_𝗋𝖺𝗇𝖽𝗈𝗆_𝗉𝗂𝖼𝗄(V) function that, given a set of values V, returns a value vV pseudo-randomly.

3.2 Problem Formalization

Outputs.

In an execution, a process pP outputs a value v{0,1} using the operation 𝗈𝗎𝗍𝗉𝗎𝗍 v. In a given execution, each process pP outputs at most one value. Hence, all its invocations of the 𝗈𝗎𝗍𝗉𝗎𝗍 operation must have the same value.

We often use the XOR operation to obtain the one’s complement of a bit v{0,1}. The logical formula we use is 1v, which gives 1 if v=0, and 0 if v=1.

Tasks.

We define a task T as a relation between input vectors Vin=(vin1,,vinn) and output vectors Vout=(vout1,,voutn), where vini and vouti are the input and output values of process pi, respectively. That is, we have (Vin,Vout)T if and only if Vout is a possible output of the task when the input is Vin. The elements vini of an input vector Vin belong to the set 𝕀{}, where 𝕀 is the input alphabet and is a sentinel value (not in 𝕀) that represents no input. Similarly, the elements vouti of an output vector Vout belong to the set 𝕆{}, where 𝕆 is the output alphabet and is a special value (not in 𝕆) that represents no output. In this work we consider only binary-output tasks, i.e., 𝕆={0,1}. Observe that a task T can have several possible outputs for the same input. By abuse of notation, we denote the set of all outputs Vout of T for an input Vin as T(Vin)={Vout(Vin,Vout)T}.

Output sets.

In this work, we will not differentiate output vectors that contain the same set of different output values. For that, we use the following notation for the set of distinct values in an output vector Vout, which we call an output set: OS(Vout)={voutiVoutvouti}. Since we consider only binary-output tasks, it holds that OS(Vout)2{0,1}={,{0},{1},{0,1}}.

We then define the set of output sets of a pair task/input vector (T,Vin) as the set of all possible output sets that can be produced by executing T with Vin: SOSI(T,Vin)={OS(Vout)VoutT(Vin)}. Observe that SOSI(T,Vin){,{0},{1},{0,1}}, and that SOSI(T,Vin)= occurs when T(Vin)=, because there is no Vout such that (Vin,Vout)T.

Finally, we define the set of output sets of a task T as the set of all possible output sets that T can produce with all possible input vectors Vin: SOS(T)={OS(Vout)Vin(𝕀{})n:VoutT(Vin)}. Observe again that SOS(T){,{0},{1},{0,1}}. Hence, all tasks T can be classified into 16 classes, each characterized by which subset of {,{0},{1},{0,1}} the set of output sets SOS(T) is.

Algorithms and executions.

An algorithm A defines the steps taken by each process pP as a function of its local state (including its input) and the communication observed. The algorithm A combined with input Vin is denoted A(Vin). An execution E of A(Vin) is a (finite or infinite) sequence of steps taken by processes following algorithm A with input Vin, combined with the observation of communication events. The output of an execution E of A(Vin) is the vector Vout with the output value that is produced in E by each process p, or if no value is output by the process.

Failure and communication patterns.

A failure pattern defines in an execution the identity of faulty processes and the time instant each faulty process stops taking steps. The possible failure patterns in an execution depend on n and the value of ft when defined, which is the exact number of failures. We denote the set of all failure patterns for a given pair (n,f) by FP(n,f).

A communication-delay pattern defines the delay experienced by each communication in the execution. The possible communication-delay patterns in an execution depend on the synchrony (σ{Async,Sync}) of the system. We denote the set of all communication-delay patterns for a given σ by CDP(σ).

Since we only consider deterministic algorithms and local computation is instantaneous, an execution is fully characterized by the tuple (A,Vin,sd,fp,cdp), where A is the algorithm, Vin the input vector, sd is the seed of the PRNG, fp is the failure pattern, and cdp is the communication-delay pattern.

Implementation of a set of output sets.

A system configuration is a triple C=(n,t,σ), where n is the number of processes, t is the maximum number of crashed processes in any execution E, and σ{Async,Sync} defines the timing model of the distributed system in which E runs.

Definition 1 (Implementation of a set of output sets).

Algorithm A implements the non-empty set of output sets O{,{0},{1},{0,1}} under system configuration C=(n,t,σ) with σ{Async,Sync} if for all 0ft, we have the following properties.

  • Safety: For all Vin, all possible PRNG seeds sd, all failure patterns fpFP(n,f), and all communication-delay patterns cdpCDP(σ), all executions (A,Vin,sd,fp,cdp) of A(Vin) in a system with n processes, f failures, and timing model σ, have output vectors Vout such that OS(Vout)O.

  • Completeness: For each oO, there is a Vin, a PRNG seed sd, a failure pattern fpFP(n,f), and a communication-delay pattern cdpCDP(σ), such that execution (A,Vin,s,fp,cdp) of A(Vin) has an output vector Vout where OS(Vout)=o.

Definition 2 (Binary-output task solvability).

Given a binary-output task T with non-empty set of output sets SOS(T), task T can be solved under system configuration C=(n,t,σ) with σ{Async,Sync} only if there is an algorithm A that implements SOS(T) under that configuration.

In the above definitions, we exclude the degenerate case where the set of output sets is empty.

Table 2: Characterization of the tight conditions for implementing the 16 sets of output sets.
#
Exact set of
output sets O
Timing
model
Tight solvability
condition
Necessity proof
Sufficiency proof
1 ,{0},{1},{0,1}
Async
& Sync
nt,n2 Observation 3
Algorithm 3 / Theorem 16
with V={0,1,}
2 ,{0},{1},{0,1}
Async
& Sync
n>t,n2 Observation 3
Algorithm 3 / Theorem 16
with V={0,1}
3 ,{0},{1},{0,1}
Async
& Sync
nt,n2 Observation 3
Algorithm 5 / Theorem 18
with v=1, 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎
4 ,{0},{1},{0,1}
Async
& Sync
n>t,n2 Observation 3
Algorithm 5 / Theorem 18
with v=1, 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎
5 ,{0},{1},{0,1}
Async
& Sync
nt,n2 Observation 3
Algorithm 5 / Theorem 18
with v=0, 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎
6 ,{0},{1},{0,1}
Async
& Sync
n>t,n2 Observation 3
Algorithm 5 / Theorem 18
with v=0, 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎
7 ,{0},{1},{0,1} Async n>32t+1,n2 Observation 3 & Theorem 5
Algorithm 1 / Theorem 10
with 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎
Sync nt+2,n2 Observation 3 & Theorem 4
Algorithm 2 / Theorem 15
with 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎
8 ,{0},{1},{0,1} Async n>32t+1,n2 Observation 3 & Theorem 5
Algorithm 1 / Theorem 10
with 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎
Sync nt+2,n2 Observation 3
Algorithm 2 / Theorem 15
with 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎
9 ,{0},{1},{0,1}
Async
& Sync
nt,n1 Observation 3
Algorithm 4 / Theorem 17
with 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎
10 ,{0},{1},{0,1} Async t=0,n1 Observation 3 & [2, 12]
Algorithm 4 / Theorem 17
with 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎
Sync n>t,n1 Observation 3 Algorithm 6 / Theorem 19
11 ,{0},{1},{0,1}
Async
& Sync
nt,n1 Observation 3
Algorithm 3 / Theorem 16
with V={1,}
12 ,{0},{1},{0,1}
Async
& Sync
n>t,n1 Observation 3
Algorithm 3 / Theorem 16
with V={1}
13 ,{0},{1},{0,1}
Async
& Sync
nt,n1 Observation 3
Algorithm 3 / Theorem 16
with V={0,}
14 ,{0},{1},{0,1}
Async
& Sync
n>t,n1 Observation 3
Algorithm 3 / Theorem 16
with V={0}
15 ,{0},{1},{0,1}
Async
& Sync
nt,n0 Observation 3
Algorithm 3 / Theorem 16
with V={}
16 ,{0},{1},{0,1}
Async
& Sync
N/A N/A N/A

4 Tight Solvability Conditions for Binary-Output Tasks

In this section, we introduce Table 2, which presents an exhaustive characterization of the tight conditions to implement all 16 possible binary sets of output sets, providing a necessary condition to solve their corresponding tasks. The first column is the line index. The second column corresponds to the set of output sets (the crossed sets in red are the forbidden output sets). The third column specifies the timing model assumed (Async, Sync, or any model if the tightness proof does not depend on timing assumptions). The fourth column provides the tight (i.e., necessary and sufficient) system condition on n (the system’s size) and t (the crash-resilience) to implement the given set of output sets under the corresponding timing model. The fifth column refers to the necessity proof of the tight condition, while the sixth column refers to its sufficiency proof.

We can observe that many well-studied tasks map to a set of output sets in Table 2. Line 10 maps to the set of output sets of classical binary consensus (i.e., each execution outputs either 0 or 1) [12], while line 9 maps to abortable [5, 10] or randomized [4] binary consensus (i.e., some executions may never terminate and output a value). Line 8 maps to 2-renaming [8] (i.e., renaming of only 2 processes in the system). Line 2 maps to 2-set agreement [9] (up to 2 different values can be output by the system). Line 4 (and its symmetric counterpart, line 6) maps to strong symmetry-breaking [3]: 1 is always output, but 0 can also be output in favorable conditions (e.g., all processes participate, or there are no crashes).

Remark that we prove the necessity of the condition t=0 to solve the Async case of line 10 (implementing the set of output sets {{0},{1}}) by relying on the FLP theorem [12]. However, unlike the original FLP paper, which assumes a message-passing network, our model does not assume a particular communication medium. For this reason, we rely on the medium-agnostic impossibility proof of asynchronous resilient consensus presented in [2].

5 Necessity: Impossibility Proofs

In this section, we prove the necessity of the tightness conditions of Table 2, by showing the impossibility of implementing the corresponding sets of output sets when these conditions are not satisfied.

Observation 3.

Under any timing model (Async or Sync), the following conditions are necessary to implement a set of output sets O:

nmax({|o|:oO}), and ntmin({|o|:oO}).

Proof.

Let us consider a set of output sets O. Condition nmax({|o|:oO}) is necessary for implementing O, otherwise there would not be enough processes to output all the values of the largest oO, violating completeness. Condition ntmin({|o|:oO}) is also necessary for implementing O. Otherwise, when f=t, there would not be enough processes guaranteed to stay correct to output all the values of the smallest oO, violating safety.

Theorem 4.

Under any timing model (Async or Sync), the condition nt2 is necessary for implementing the set of output sets O={,{0,1}}.

Proof.

We prove the lemma by contradiction: assume that there is an algorithm A that can implement O={,{0,1}} under nt<2. This means that at least n1 processes can crash during an execution.

Let us consider an execution Ec of A that produces output set {0,1}. This execution must exist for completeness. In particular, let us consider the first process pP that outputs some value v{0,1} in Ec with respect to the global time, and let τ be the time when p outputs v.111If multiple processes simultaneously output a value at time τ, we pick any of these processes, as their respective outputs cannot have physically influenced each other. Then, it is possible to craft an execution E that is exactly the same as Ec up to time τ, at which time all processes except p crash before outputting anything, and p is correct. In execution E, the output set is {v}, which violates safety: contradiction.

Theorem 5.

Under Async, condition n>32t+1 is necessary for implementing the sets of output sets O={{0,1}} and O={,{0,1}}.

Proof.

By contradiction, let us assume that there exists an algorithm A that implements the set of output sets {{0,1}} or {,{0,1}} under Async and n32t+1. Note that n2, from Observation 3, which implies that t1.

We first prove that, no matter the case (whether A implements {{0,1}} or {,{0,1}}), A must have a crash-free execution E0 producing the output set {0,1}.

  • If A implements the set of output sets {{0,1}}, then any crash-free execution of A can only output set {0,1}.

  • If A implements the set of output sets {,{0,1}}, then we consider any execution Ec of A that outputs set {0,1} but that may present crashes. Let us denote by Pd the set of processes that output any value in Ec, and by Pc the set of processes that crash in Ec. We can construct an execution E0 of A that is the same as Ec, except that it has no crash, and all information communicated by processes of Pc after the point where they would crash in Ec is delayed due to asynchrony, such that it is only observed by processes of Pd after they produce their outputs. Therefore, the outputs of the processes of Pd cannot have been influenced by the fact that the processes in Pc are correct, and E0 must also produce the output set {0,1}.

We therefore refer to E0 as a crash-free execution of A producing the output set {0,1}. Let p1P be the first process that outputs some value v1{0,1} in E0 w.r.t. global time (at time τ1). Let execution E1 be an execution that is the same as E0 up to τ1, but where p1 crashes immediately after it outputs v1.

We now construct a sequence of executions E2,,Et of A inductively as follows. Let us consider some i=2,,t. To construct Ei, we assume by induction hypothesis that, in execution Ei1 (starting with E1), process p1 outputs value v1, therefore Ei1 must necessarily produce the output set {0,1} (it cannot produce the output set anymore). Hence, there must be another process in the system that outputs the opposite value 1v1 in Ei1. In particular, there must be some process piP which is the second one (after p1) to output a value vi{0,1} in Ei1 (w.r.t. global time) at time τi. We then make execution Ei the same as Ei1 until time τi, but we make process pi crash just before it outputs a value, leaving p1 be the only process that outputs a value in Ei up to time τi.

When we reach execution Et, there have been t process crashes, so we cannot crash processes anymore. Finally, we denote by pt+1 the second process that outputs some value in Et at time τt+1, w.r.t. global time.

We now create a new crash-free execution Ecrash-free that is the same as Et, except that all processes p1,,pt do not crash, but all communication that they make after their respective output is delayed until τt+1. Then, for any process pP{p1,,pt}, prior to τt+1, Ecrash-free is indistinguishable from Et from the point of view of p. In other words, in Ecrash-free, the processes of {p1,,pt} are indistinguishable from crashed processes to the other processes, before τt+1.

Let us consider the set of processes {p1,,pt+1} in Ecrash-free. We can divide this set into two partitions: the subset P0 of processes that output 0 in Ecrash-free, and the subset P1 of processes that output 1 in Ecrash-free. Let us denote by Pmin (resp., Pmaj) the smaller (resp., bigger) set between P0 and P1 (if they have the same size, then Pmin is P0 and Pmaj is P1). Remark that |Pmin|+|Pmaj|=t+1 and |Pmin|t+12|Pmaj|. We then denote by P? the subset of processes that are not in Pmin or Pmaj: P?=P{p1,,pt+1}. We have |P?|=nt132t+1t1=t2. Moreover, we have |Pmin|+|P?|t+12+t2=t+12. But as |Pmin|, |P?|, and t are all integers, then we also have |Pmin|+|P?|t.

Figure 1: Execution Ecrash, where processes of Pmin and P? crash, and only processes of Pmaj stay correct, which leads to a safety violation.

As illustrated in Figure 1, we can finally construct another execution Ecrash, which is the same as Ecrash-free up to time τt+1, except that we make all processes of Pmin and P? crash in Ecrash immediately before their output step (as |Pmin|+|P?|t). After time τt+1, the only remaining correct processes in Ecrash are those of Pmaj. The processes of Pmaj all output the same value v (v=0 if Pmaj=P0, v=1 if Pmaj=P1), thus producing the output set v. Hence, safety is violated, and we have a contradiction.

6 Sufficiency: Implementing Algorithms

In this section, we provide algorithms, along with their correctness proofs, implementing the binary sets of output sets of Table 2. For modularity and conciseness, the algorithms of this paper feature instantiation parameters, which allow each one of them to have several possible behaviours, and thus implement multiple sets of output sets in Table 2.

For the sake of presentation clarity, some algorithms and proofs used in Table 2 are presented in detail in Appendix A. This section focuses on the algorithms implementing lines 7 and 8 of Table 2 (Algorithm 1 for the Async case, Algorithm 2 for the Sync case), which we deem the most interesting ones in our classification. We call them disagreement algorithms, since they must always guarantee that the system never outputs only one single value (0 or 1). More specifically, in every execution of a disagreement algorithm, there must be at least one process that outputs 0 and at least one that outputs 1.

6.1 Asynchronous Disagreement Algorithm (Lines 7–8)

The algorithm of this section (Algorithm 1) addresses the Async case of lines 7 and 8 in Table 2. It is instantiated by providing a Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎} (line 1), which determines if the empty output set can be produced or not.

At the initialization of the algorithm, the set of processes P is partitioned into three subsets, P0,P1,P? (line 2), which respectively contain at least t+12, t2, and t+12 processes. By combining this with the system assumption, we obtain that the union of any two of these subsets contains at least one correct process. Moreover, a set of at least t+1 processes PinitP is also selected (which is only used when 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎).

Every process pinitPinit passes the condition at line 4 only if is not a forbidden output set (𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎) and it pseudo-randomly picks 0. If it does, pinit communicate init. Every process pvPv,v{0,1} first checks if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 (line 6). If it does, pv waits until it observes some init information. If pv passes the previous line, it will then output v (line 7) and communicate output(v) (line 8). Every process p?P? first waits until it observes some output(v) (line 10). If it passes this 𝗐𝖺𝗂𝗍 statement, then p? outputs the opposite of v, namely 1v (line 11).

Before proving the correctness of Algorithm 1, we first show some intermediary results.

Algorithm 1 Disagreement asynchronous algorithm for the Async case of lines 7-8 of Table 2, assuming 32t+1<n2.
Observation 6.

Since P0 and P1 are disjoint, we have |P0P1|t+12+t2=t+12. Moreover, as the left-hand side is an integer, then we also have |P0P1|t+1, hence there is at least one correct process pvcP0P1.

Lemma 7.

If some process pP? outputs a value v{0,1} at line 11, then another process pP1v also outputs the opposite value 1v at line 7.

Proof.

If some pP? outputs v at line 11, then it must have observed some output(1v) at line 10. By C-Validity, this output(1v) was communicated by some process pP1v at line 8, after it had output 1v at line 7.

Lemma 8.

If a process pP0P1 outputs some value v{0,1} at line 7, then all correct processes in P0P1 pass line 6.

Proof.

Let us assume that some process pP0P1 outputs a value v{0,1}. We now show that all correct processes in P0P1 pass line 6.

  • If 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎, then this is immediate.

  • If 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎, then all correct processes in P0P1 reach the 𝗐𝖺𝗂𝗍 statement at line 6. However, since p reached line 7, it must have passed that 𝗐𝖺𝗂𝗍, thus observing some init. By C-Global-termination, all correct processes in P0P1 also observe init and therefore pass line 6.

Lemma 9.

If some process pP outputs some value v{0,1}, then another process pP{p} also outputs the opposite value 1v.

Proof.

Let us assume that some process pP outputs a value v{0,1}. If pP?, then Lemma 7 states that the execution must produce the output set {0,1} and we are done. Otherwise, if pP0P1, then Lemma 8 applies, and all correct processes in P0P1 pass line 6. We consider the following two opposite cases.

  1. 1.

    Case (i): At least one correct pP? exists. As all correct processes in P0P1 pass line 6, then, in particular, correct process pvcP0P1 (Observation 6) reaches line 8 and communicates some output(). By C-Local-termination and C-Global-termination, p will eventually observe this output() information, and will therefore pass the 𝗐𝖺𝗂𝗍 statement at line 10 (either after it observed the output() communicated by pvc, or because it observed some prior output()). Finally, p will reach line 11 and output some value v{0,1}. Lemma 7 therefore applies, and some other process p′′P1v also outputs the opposite value 1v.

  2. 2.

    Case (ii): All processes in P? crash. In this case, at least t+12 crashes have already occurred on all processes of P?, and the maximum number of remaining crashes is tt+12.

    • If t is even, then t+12=t+22=t2+1 and tt+12=tt21=t21<t2.

    • If t is odd, then t+12=t+12 and tt+12=tt+12=t12<t2.

    Therefore, it is not possible to also crash all processes of P0 or P1, since they both contain at least t2 processes. This implies that there are at least two correct processes p0P0,p1P1. Since all correct processes in P0P1 pass line 6 (Lemma 8), then p0 and p1 both reach line 7, and respectively output 0 and 1.

Therefore, in every case, if some value v{0,1} is output by a process pP, the opposite value 1v is also output by another process pP{p}.

Theorem 10.

Under Async and 32t+1<n2, Algorithm 1 instantiated with Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎} implements the following sets of output sets:

O={{{0,1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎,{,{0,1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎.

Proof.

We first show that condition 32t+1<n2 is sufficient to construct the sets of processes used in Algorithm 1, namely P0,P1,P?,Pinit.

  • If t is even, then 32t is an integer and n>32t+1 implies n32t+2. Also, t2 is an integer. Hence, there are enough processes to set |P0|t2+1, |P1|t2, and |P?|t2+1, thus satisfying the conditions of line 2. This implies that |P0|+|P1|+|P?|=32t+2, as desired.

  • If t is odd, then 3t12 is an integer and 32t=3t12+12. Then n>32t+1 implies n3t12+2. Also, t12 is an integer. Hence, there are enough processes to set |P0|t12+1, |P1|t+12, and |P?|t12+1, thus satisfying the conditions of line 2. This implies that |P0|+|P1|+|P?|=3t12+2, as desired.

Furthermore, since we have n>32t+1t+1 and |Pinit|t+1, then there are also enough processes to construct the set Pinit. Note also that n2 is already implied by n>32t+1. We consider the following two opposite cases.

  • Case 1: 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎. We must show O={{0,1}}.

  • Case 2: 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎. We must show O={,{0,1}}.

We now prove that the following safety and completeness results hold for both Cases 1 and 2.

  1. 1.

    General-Safety: Impossibility of {0} and {1} in Cases 1 and 2. By corollary of Lemma 9, the output sets {0} and {1} cannot happen.

  2. 2.

    General-Completeness: Possibility of {0,1} in Cases 1 and 2. Let us first show that there is an execution where the correct process pvcP0P1 (Observation 6) passes line 6.

    • In Case 1, we have 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎, so pvc passes this line.

    • In Case 2, we have 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎, so pvc reaches the 𝗐𝖺𝗂𝗍 statement at line 6. However, since we have |Pinit|t+1, there is at least one correct process pinitcPinit, and there exists an execution where pinitc picks 0 and then communicates init at line 4, thus unlocking pvc at line 6.

    Therefore, there is an execution where pvc passes line 6, and then outputs some value v{0,1} at line 7. By Lemma 9, another process also outputs the opposite value 1v, thus producing the output set {0,1}.

The safety of Case 2 follows from General-Safety. For Case 1, we also have to prove the impossibility of . Since 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 in Case 1, correct process pvc (Observation 6) passes the condition at line 6 and outputs some v{0,1} at line 7, and thus is impossible.

The completeness of Case 1 follows from General-Completeness. For Case 2, we also have to prove the possibility of . Since 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 in Case 2, there is an execution where no process from Pinit communicates init at line 4 (because all processes in Pinit either crashed or picked 1 at line 4). In this execution, no process in P0P1 passes the 𝗐𝖺𝗂𝗍 statement at line 6, and no process in P? passes the 𝗐𝖺𝗂𝗍 instruction at line 10. Therefore, no process outputs any value in this execution, thus producing output set .

6.2 Synchronous Disagreement Algorithm (Lines 7–8)

The algorithm of this section (Algorithm 2) addresses the Sync case of lines 7 and 8 in Table 2. It is instantiated by providing a Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎} (line 1), which determines if the empty output set can be produced or not.

At the initialization of the algorithm, all processes of P are divided into two totally-ordered sequences S0 and S1, of n2 and n2 processes respectively, such that |S0|+|S1|=n. Informally, the value v{0,1} of a sequence Sv corresponds to the default value that the processes of Sv output if they did not observe that another process already output this value before. The index i of every process piv in a sequence Sv determines the round numbers in which piv will output a value (round i) and communicate information (round i+1). Moreover, a set of at least t+1 processes PinitP is also selected (which is only used when 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎). Each process pivSv also has a local variable vchosen, initialized to the sentinel value , which stores the output value of piv between round i and i+1.

Every process pinitPinit passes the condition at line 5 only if is not a forbidden output set (𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎) and it pseudo-randomly picks 0. If it does, pinit communicate init. Every process pivSv (v{0,1}) only performs actions during synchronous rounds i and i+1 (if i<n2), because of the conditions at lines 7 and 8.

During synchronous round i, piv does not pass the condition at line 7 during the communication step, but it can enter the condition at line 8, if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 or if it observed some init. If it enters the condition, then it updates its vchosen local variable: vchosen stores the opposite of piv’s default value v if it observed that another process in the system already output its v, otherwise vchosen stores v (line 9). Finally, piv outputs vchosen (line 10).

During synchronous round i+1 (if i<n2), piv passes the condition at line 7 if it has output a value in the previous round (i.e., vchosen). If it does, it communicates its output value through some output(vchosen) information (line 7).

Before proving the correctness of Algorithm 2, we first show some intermediary results.

Algorithm 2 Disagreement synchronous algorithm for the Sync case of lines 7-8 of Table 2, assuming t+2n2.
Lemma 11.

There must be two distinct correct processes pivSv,pjvSv for v,v{0,1} and i,j[1..n2].

Proof.

Since nt+2, then there are at least two correct processes p,pP. Moreover, by definition, all processes p′′P belong to S0 or S1, so p,p belong to either S0 or S1, and their indices in these sequences are comprised between 1 and n2.

Lemma 12.

If some process pP outputs a value w{0,1} at line 10, then two correct processes pivSv,pjvSv (where i,j[1..n2] and v,v{0,1}) also output some values v1,v2{0,1} at line 10.

Proof.

Assume some process pP outputs a value w{0,1} at line 10 during synchronous round k[1..n2]. Let us also consider the two correct processes piv,pjv belonging to either S0 or S1 (Lemma 11), where i,j[1..n2] are round numbers and v,v{0,1} are default output values. Process p must have satisfied the condition at line 8, which leads to two opposite cases.

  • If 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎, then piv,pjv do the following during round number i and j, respectively: they enter the condition at line 8, reach line 10 and output some value in {0,1}.

  • If 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎, then p has observed some init information, which, by C-Validity, must have been communicated during round 1 by some process pinitPinit at line 5. Moreover, by C-Global-termination and C-Synchrony, all correct processes in P must also observe some init information by the end of round 1. In particular, correct processes piv,pjv respectively satisfy the condition at line 8 at rounds i,j, reach line 10, and output some values v1,v2{0,1}.

Therefore, piv,pjv always output some values v1,v2{0,1} at line 10.

Lemma 13.

If some process pjvSv outputs the opposite of its default value 1v{0,1} at line 10 during round j[2..n2], then some other process pkP must have output v in a previous round k<j.

Proof.

If a process pjvSv outputs the opposite of its default value 1v{0,1} at line 10 during round j[2..n2], then it must have chosen vchosen=1v at line 9, and therefore it must have observed some output(v) information. By C-Validity, this output(v) must have been communicated by some process pkP at line 7 at the beginning of round k+1 (where 2k+1j). Moreover, pk must have output v at line 10 during round k (where 1k<j).

Lemma 14.

If some process pP outputs a value v{0,1} at line 10, then another process pP{p} also outputs the opposite value 1v at line 10.

Proof.

Let us assume that some process pP outputs a value v{0,1} at line 10. By Lemma 12, two correct processes piv,pjv belonging to either S0 or S1 respectively output some values v1,v2{0,1} at line 10, during synchronous rounds i,j[1..n2].

If either piv or pjv output the opposite of their default value (i.e., if v1=1v or v2=1v), then Lemma 13 applies, and there is another process pk that outputs v3, which is the opposite value that they output (i.e., v3=1v1 if v1=1v, or v3=1v2 if v2=1v), so we are done. Therefore, in the following, we assume that piv and pjv output their default values, i.e., v1=v and v2=v. We consider the following two cases.

  • Case (i): i=j. In this case, piv and pjv both output during the same synchronous round i=j. As piv and pjv are distinct processes, then they cannot belong to the same sequence S0 or S1, and we must have vv. But since piv and pjv respectively output v and v, then they output opposite values.

  • Case (ii): i<j (without loss of generality). In this case, piv has output before pjv, i[1..n21], and j[2..n2]. Let us remark that correct process piv must have communicated output(v1) at line 7 during round i+1 (where 2i+1j), after it has ouput v1 at line 10 during round i. By C-Local-termination, C-Global-termination, C-Synchrony, pjv must have observed output(v1) by the end of round i+1j. However, since v2=v (i.e., pjv outputs its default value v), by line 9, pjv has not observed any output(v) information during or before round j2. This necessarily means that v1v=v2, and therefore that piv and pjv output opposite values (i.e., v1=1v2).

Whether in Case (i) or Case (ii), processes piv and pjv output opposite values at line 10 (i.e., v1=1v2), which concludes the lemma.

Theorem 15.

Under Sync and t+2n2, Algorithm 2 implements the following sets of output sets:

O={{{0,1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎,{,{0,1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎.

Proof.

We first show that condition t+2n2 is sufficient to construct the sequences and set of processes used in Algorithm 1: S0,S1,Pinit. Since we have n=n2+n2=|S0|+|S1|, then there are enough processes to construct the sequences of distinct processes S0,S1. Furthermore, since we have nt+2 and |Pinit|t+1, then there are enough processes to construct the set Pinit. Let us also remark that n2 is already implied by nt+2. We consider the following two opposite cases.

  • In Case 1, we have 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎. In this case, we must prove that the set of output sets is O={{0,1}}.

  • In Case 2, we have 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎. In this case, we must prove that the set of output sets is O={,{0,1}}.

We now prove that the following safety and completeness results hold for both Cases 1 and 2.

  1. 1.

    General-Safety: Impossibility of {0} and {1} in Cases 1 and 2. By corollary of Lemma 14, the output sets {0} and {1} cannot happen.

  2. 2.

    General-Completeness: Possibility of 0,1 in Cases 1 and 2. By Lemma 11, there is a correct process piv in S0 or S1 that reaches the condition at line 8 during synchronous round i[1..n2]. Let us show that, no matter the case, there is an execution where piv passes the condition at line 8.

    • In Case 1, we have 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎, so piv satisfies the condition line 8 at round i.

    • In Case 2, we have 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎. Since we have |Pinit|t+1, there is at least one correct process pinitcPinit, and there exists an execution where pinitc picks 0 and then communicates init at line 2 during round 1. By C-Local-Termination, C-Global-termination, and C-Synchrony, piv observes init by the end of round 1, and therefore, when it reaches round i1, the condition at line 8 is satisfied.

    Therefore, there is an execution where piv passes line 8, and then outputs some value v{0,1} at line 10 during round i. By Lemma 14, another process also outputs the opposite value 1v, thus producing the output set {0,1}.

The safety of Case 2 follows from General-Safety. For Case 1, we also have to prove the impossibility of . By Lemma 11, there is a correct process piv belonging to S0 or S1. As 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 in Case 2, then piv must pass line 8 during round i[1..n2], reach line 10, and output some value v{0,1}. Therefore, the output set is impossible.

The completeness of Case 1 follows from General-Completeness. For Case 2, we have to prove the possibility of . Since 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 in Case 2, there is an execution where no process from Pinit communicates init at line 2 (because all processes in Pinit either crashed or picked 1 at line 2). In this execution, no process in P passes line 8, and therefore, no process outputs any value in this execution, thus producing output set .

7 Conclusion

In this work, we exhaustively characterize solvability conditions for binary-output tasks under crash failures. More particularly, we focus on the sets of distinct output values that executions of these tasks can produce, which breaks down binary-output tasks into 16 classes. Our results cover both necessity, via impossibility proofs, and sufficiency, via implementing algorithms, thereby offering a definitive picture (Table 2) of the boundary between possible and impossible. By abstracting away from specific input assumptions and focusing on possible outputs, the conditions we present also serve as lower bounds (albeit not necessarily tight) for any stronger problem formulation. Let us also remark that our necessary conditions apply to all types of tasks (whether colored or colorless [15]), while our sufficient conditions only apply to input-independent, binary-output, colorless tasks.

Some of the results connect back to some well-studied problems, such as binary consensus and symmetry breaking, as discussed in Section 4. One particularly interesting problem we discovered is the disagreement problem that requires the system to never “agree” on one single output value (0 or 1). To our knowledge, this particular problem has not been studied before, and it illustrates how our framework exposes subtle but fundamental problems that are not captured by classical formulations.

We propose in the following some possible extensions to our current framework. Currently, we do not require that all correct processes eventually output some value. It is left for future work to explore whether adding this requirement will change the conditions. Exploring the tight conditions in partial synchronous environments is another interesting venue. Observe that, in the cases where the tight conditions are the same in both synchrony and asynchrony, then they are also tight for partial synchrony. We leave the remaining cases (e.g., disagreement) to future investigation. Another logical extension would be to consider multi-valued outputs (i.e., not limited to 0/1), which will significantly increase the number of possible sets of output sets. Moreover, output sets hide some structural information of output values, such as their multiplicity or the information about which process outputs the value. This can be done by adding additional information to output sets or by directly studying output vectors. Finally, the task input and validity constraints (relation between input and output) are also aspects to be explored in future work.

References

  • [1] Marcos Kawazoe Aguilera and Sam Toueg. A simple bivalency proof that t-resilient consensus requires t+1 rounds. Inf. Process. Lett., 71(3-4):155–158, 1999. doi:10.1016/S0020-0190(99)00100-3.
  • [2] Timothé Albouy, Antonio Fernández Anta, Chryssis Georgiou, Mathieu Gestin, Nicolas Nicolaou, and Junlang Wang. AMECOS: a modular event-based framework for concurrent object specification. In Proc. 28th Int’l Conference on Principles of Distributed Systems (OPODIS’24), volume 324 of LIPIcs, pages 4:1–4:29. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2024. doi:10.4230/LIPICS.OPODIS.2024.4.
  • [3] Hagit Attiya and Ami Paz. Counting-based impossibility proofs for set agreement and renaming. J. Parallel Distributed Comput., 87:1–12, 2016. doi:10.1016/J.JPDC.2015.09.002.
  • [4] Michael Ben-Or. Another advantage of free choice: Completely asynchronous agreement protocols (Extended abstract). In Proc. 2nd ACM Symposium on Principles of Distributed Computing (PODC’83), pages 27–30. ACM, 1983. doi:10.1145/800221.806707.
  • [5] Romain Boichat, Partha Dutta, Svend Frølund, and Rachid Guerraoui. Deconstructing Paxos. SIGACT News, 34(1):47–67, 2003. doi:10.1145/637437.637447.
  • [6] Gabriel Bracha. Asynchronous Byzantine agreement protocols. Inf. Comput., 75(2):130–143, 1987. doi:10.1016/0890-5401(87)90054-X.
  • [7] Armando Castañeda, Damien Imbs, Sergio Rajsbaum, and Michel Raynal. Generalized symmetry breaking tasks and nondeterminism in concurrent objects. SIAM J. Comput., 45(2):379–414, 2016. doi:10.1137/130936828.
  • [8] Armando Castañeda, Sergio Rajsbaum, and Michel Raynal. The renaming problem in shared memory systems: An introduction. Comput. Sci. Rev., 5(3):229–251, 2011. doi:10.1016/J.COSREV.2011.04.001.
  • [9] Soma Chaudhuri. More choices allow more faults: Set consensus problems in totally asynchronous systems. Inf. Comput., 105(1):132–158, 1993. doi:10.1006/INCO.1993.1043.
  • [10] Wei Chen. Abortable consensus and its application to probabilistic atomic broadcast. Technical report, Microsoft Research Asia, 2007. URL: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-2006-135.pdf.
  • [11] Danny Dolev, Rüdiger Reischuk, and H. Raymond Strong. Early stopping in Byzantine agreement. J. ACM, 37(4):720–741, 1990. doi:10.1145/96559.96565.
  • [12] Michael J. Fischer, Nancy A. Lynch, and Mike Paterson. Impossibility of distributed consensus with one faulty process. J. ACM, 32(2):374–382, 1985. doi:10.1145/3149.214121.
  • [13] Eli Gafni and Sergio Rajsbaum. Musical benches. In Proc. 19th Int’l Conference on Distributed Computing (DISC’05), volume 3724 of Lecture Notes in Computer Science, pages 63–77. Springer, 2005. doi:10.1007/11561927_7.
  • [14] Vassos Hadzilacos and Sam Toueg. Reliable broadcast and related problems. In Sape Mullender, editor, Distributed Systems, pages 97–145. Addison-Wesley, Reading, MA, 2nd edition, 1993. Chapter 5.
  • [15] Maurice Herlihy, Dmitry N. Kozlov, and Sergio Rajsbaum. Distributed Computing Through Combinatorial Topology. Morgan Kaufmann, 2013. URL: https://store.elsevier.com/product.jsp?isbn=9780124045781.
  • [16] Maurice Herlihy and Nir Shavit. The topological structure of asynchronous computability. J. ACM, 46(6):858–923, 1999. doi:10.1145/331524.331529.
  • [17] Damien Imbs, Sergio Rajsbaum, and Michel Raynal. The universe of symmetry breaking tasks. In Proc. 18th Int’l Colloquium on Structural Information and Communication Complexity (SIROCCO’11), volume 6796 of Lecture Notes in Computer Science, pages 66–77. Springer, 2011. doi:10.1007/978-3-642-22212-2_7.
  • [18] Donald E. Knuth. The art of computer programming, volume 2 (3rd ed.): seminumerical algorithms. Morgan Kaufmann, 1997.
  • [19] Ephraim Korach, Shay Kutten, and Shlomo Moran. A modular technique for the design of efficient distributed leader finding algorithms. ACM Trans. Program. Lang. Syst., 12(1):84–101, 1990. doi:10.1145/77606.77610.
  • [20] Nancy A. Lynch. Distributed Algorithms. Morgan Kaufmann, 1996.
  • [21] Achour Mostéfaoui, Sergio Rajsbaum, and Michel Raynal. Conditions on input vectors for consensus solvability in asynchronous distributed systems. J. ACM, 50(6):922–954, 2003. doi:10.1145/950620.950624.
  • [22] Michel Raynal. Consensus in synchronous systems: A concise guided tour. In Proc. 9th Pacific Rim Int’l Symposium on Dependable Computing (PRDC’02), pages 221–228. IEEE Computer Society, 2002. doi:10.1109/PRDC.2002.1185641.
  • [23] Armando Castañeda Rojano. A study of the wait-free solvability of weak symmetry breaking and renaming. PhD thesis, Universidad Nacional Autónoma de México, 2010.
  • [24] Nicola Santoro and Peter Widmayer. Time is not a healer. In Proc. 6th Annual Symposium on Theoretical Aspects of Computer Science (STACS’89), volume 349 of Lecture Notes in Computer Science, pages 304–313. Springer, 1989. doi:10.1007/BFB0028994.
  • [25] Eugene Styer and Gary L. Peterson. Tight bounds for shared memory symmetric mutual exclusion problems. In Proce. 8th Annual ACM Symposium on Principles of Distributed Computing (PODC’89), pages 177–191. ACM, 1989. doi:10.1145/72981.72993.
  • [26] Werner Vogels. Eventually consistent. Commun. ACM, 52(1):40–44, 2009. doi:10.1145/1435417.1435432.

Appendix A Sufficiency: Additional Algorithms and Proofs

This appendix presents the remaining algorithms and correctness proofs used for proving the sufficiency of the tightness conditions of Table 2.

A.1 Communication-Less All-Output Algorithm (Lines 1–2, 11–15)

The algorithm of this section (Algorithm 3) addresses lines 1 to 2, and 11 to 15 in Table 2. It requires no communication, as it only involves one process outputting a pseudo-random value in isolation. Therefore, this algorithm works both in the Sync and Async timing models. This algorithm is instantiated with one parameter (line 1): a set of values V{0,1,} determining all output behaviors of the algorithm. Every process pP only picks a pseudo-random value vV (line 3) and outputs this value if it is not (line 4).

Theorem 16.

Under any timing model (Async or Sync) and nmax({|o|:oO}), Algorithm 3 instantiated with the nonempty set of values V{0,1,} implements the following sets of output sets:

O={2V{}if V and t<n,2(V{})if V and tn.

Proof.

In the following lemma, we denote by PoutP the subset of processes that output a value at line 4. Let us proceed by exhaustion.

  • In Case 1, we have V and t<n. In this case, there is at least one correct process pP, and we must prove that Algorithm 3 implements the set of output sets O=2V{}. Therefore, the set of forbidden output sets is (2{0,1}2V){}.

  • In Case 2, we have V and tn. In this case, all processes could crash, and we must prove that Algorithm 3 implements the set of output sets O=2((V{})). Therefore, the set of forbidden output sets is 2{0,1}2(V{}).

We begin with general safety and completeness results that apply to both Cases 1 and 2.

  1. 1.

    General-Safety: Impossibility of all sets in 2{0,1}2(V{}) in Case 1 and 2. Let us consider a set o2{0,1}2(V{}). Since o is in 2{0,1} but not in 2(V{}), it means that o contains values that are not in V{}. But as processes only output values in V{} at line 4, then o is impossible.

  2. 2.

    General-Completeness: Possibility of all sets in 2(V{}){}. Since nmax({|o|:oO}) and all failure patterns are possible, there is a set of executions where at least max({|o|:oO}) processes pass the condition at line 4 (either because V or because all of these processes picked a non- value at line 3). In these executions, we have |Pout|max({|o|:oO}). Among these executions, and for every o2(V{}){}, there is an execution where at least |o| processes in |Pout| pick and output each of the values in o at line 4, therefore producing output set o.

Algorithm 3 Communication-less symmetric algorithm for lines 1-2 and 11-15 of Table 2.

The safety of Case 2 follows from General-Safety. For Case 1, we also need to show the impossibility of . Since V, some process p is correct, must pass the condition at line 4, and output a value at line 4. Therefore is impossible.

The completeness of Case 1 follows from General-Completeness. For Case 2, we also need to show the possibility of . There is an execution where Pout= (because all processes either crashed or picked at line 3), therefore producing output set .

A.2 Communication-Less Single-Output Algorithm (Lines 9-10)

The algorithm of this section (Algorithm 4) addresses lines 9 to 10 in Table 2. It requires no communication, as it only involves one process outputting a pseudo-random value in isolation. Therefore, this algorithm works both in the Sync and Async timing models.

This algorithm is instantiated with one parameter (line 1): a Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎}, determining if the empty output set can be produced or not. At the initialization of the algorithm (line 2), one special process pP is chosen to be the only one that performs actions (lines 3 and 6), while all other processes do nothing.

Process p first selects the set V corresponding to the different output behaviors it can follow (line 4): {0,1} if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎, or {0,1,} if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎. Then, p pseudo-randomly picks a value v from V (line 5). If v, then p outputs v at line 6, otherwise p does nothing.

Algorithm 4 Communication-less algorithm for lines 9 and 10 of Table 2, with a single process outputting and assuming n1.
Theorem 17.

Under any timing model (Async or Sync) and n1, Algorithm 4 instantiated with Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎} implements the following sets of output sets:

O={{{0},{1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and t=0,{,{0},{1}}if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 and tn.

Proof.

Let us proceed by exhaustion.

  • In Case 1, we have 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and t=0. In this case, no process can crash, and we must prove that Algorithm 4 produces the set of output sets {{0},{1}}. Therefore, the set of forbidden output sets is {,{0,1}}.

  • In Case 2, we have 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 and t0. In this case, all processes can crash, and we must prove that Algorithm 4 produces the set of output sets {,{0},{1}}. Therefore, the set of forbidden output sets is {{0,1}}.

We begin with general safety and completeness results that apply to both Cases 1 and 2.

  1. 1.

    General-Safety: Impossibility of {0,1} in Cases 1 and 2. For an algorithm to produce two outputs in some execution, there must be at least two processes in some execution that output. But by construction, in Algorithm 4, only process p can output a value at line 2.

  2. 2.

    General-Completeness: Possibility of {0} and {1} in Cases 1 and 2. Since nmax({|o|:oO}) and all failure patterns are possible, there must be some executions in which process p never crashes. Among these executions, there must be one in which p picks 0 (resp. 1) at line 5 and outputs 0 (resp. 1) at line 6, therefore producing the output set {0} (resp. {1}).

The safety of Case 2 follows from General-Safety. For Case 1, we also need to show the impossibility of . Since 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and no process can crash, p will always pick some value at line 5 and output it at line 6.

The completeness of Case 1 follows from General-Completeness. For Case 2, we also need to show the possibility of . There is some execution where p either crashes before outputting, or picks at line 5. In this execution, p will not reach line 6, therefore, producing the output set .

A.3 Timing-Adaptive Algorithm (Lines 3–6)

The algorithm of this section (Algorithm 5) addresses lines 3 to 6 in Table 2. It is timing-adaptive as it provides different control flows depending on whether the system is synchronous or asynchronous.

This algorithm is instantiated by providing two parameters (line 1): one value v{0,1} and one Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎}. Value v is the default value: it always has to be output by the system, as long as any value is output. Boolean 𝑛𝑜_𝑜𝑢𝑡 determines if the empty output set can be produced or not. At the initialization of the algorithm, one special process pP is chosen (line 2) to be the one that will guarantee that the opposite value of v (i.e., 1v) can sometimes be output if v has also been output.

Algorithm 5 Asymmetric algorithm for lines 3-6 of Table 2, assuming n2. Moreover, for lines 3 and 5 (which allow the output set), it assumes tn, and for lines 4 and 6 (which forbid the output set), it assumes t<n.

The code of every process pP that is not p is as follows (lines 3 and 6). Process p passes the condition at line 4 only if is a forbidden output set or if p pseudo-randomly flips the “correct” bit to 0. Then, p outputs v (line 5) and communicates some output(v) (line 6).

The code of process p is as follows (lines 7 and 12). Like with p, process p passes the condition at line 8 only if is a forbidden output set or if p pseudo-randomly flips the “correct” bit to 0. Then, p waits for a given time, depending on the timing model: if the system is synchronous, p waits for the communication step of synchronous round 1 (line 9), otherwise (i.e., if the system is asynchronous) it waits until some predefined local time222In this case, the assumption that, in asynchrony, every communication-delay pattern can happen, helps us to guarantee that p sometimes observes information before this local time, see Section 3.2. (line 10). After this wait, p outputs a random bit if it has observed some output(v) (line 11), otherwise it outputs the default value v (line 12).

Theorem 18.

Under any timing model (Async or Sync) and n2, Algorithm 5 instantiated with value v{0,1} and Boolean 𝑛𝑜_𝑜𝑢𝑡{𝚝𝚛𝚞𝚎,𝚏𝚊𝚕𝚜𝚎} implements the following sets of output sets:

O={{{v},{v,1v}}if 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and t<n,{,{v},{v,1v}}if 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 and tn.

Proof.

In the following lemma, we denote by PoutP the subset of processes that output a value at line 5, line 11, or line 12. Let us proceed by exhaustion.

  • In Case 1, we have 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and t<n. In this case, there is at least one correct process pP, and we must prove that Algorithm 5 produces the set of output sets {{v},{v,1v}}{}. Therefore, the set of forbidden output sets is {,{1v}}.

  • In Case 2, we have 𝑛𝑜_𝑜𝑢𝑡=𝚝𝚛𝚞𝚎 and tn. In this case, all processes could crash, and we must prove that Algorithm 5 produces the set of output sets {,{v},{v,1v}}. Therefore, the set of forbidden output sets is just {1v}.

We begin with general safety and completeness results that apply to both Cases 1 and 2.

  1. 1.

    General-Safety: Impossibility of {1v} in Cases 1 and 2. Any process pP{p} that outputs a value at line 5 will output v. Process p outputs value 1v (with some probability) only if it has observed that at least one other process has output v (line 11). C-Validity ensures that some process p first outputs v and then communicates this information (line 5 and line 6), and therefore that value v has also been output. Thus, o={1v} is impossible.

  2. 2.

    General-Completeness: Possibility of all sets in {{v},{v,1v}} in Cases 1 and 2. We first argue the possibility of {v,1v}. Since n2 and all failure patterns (and communication-delay patterns in asynchrony) are possible, there is a set of executions where process p (the selected one) and at least another process pP{p} do not crash and output a value. That is, process p passes the condition at line 4 and therefore outputs v, and process p passes the check at line 8 and observes output(v) before reaching the condition at line 11, and therefore outputs {1v}, with some non-null probability. Observe that any other process in Pout{p} outputs v, yielding the output set {v,1v}. The possibility of {v} follows similarly, for example, in executions that p crashes or also outputs v.

The safety of Case 2 follows from General-Safety. For Case 1, we also need to show the impossibility of . Since 𝑛𝑜_𝑜𝑢𝑡=𝚏𝚊𝚕𝚜𝚎 and t<n, at least one process must pass the check in line 4 or line 8 and thus output a value (either at line 5 for p, or line 11, line 12 for p). Therefore, is impossible.

The completeness of Case 1 follows from General-Completeness. For Case 2, we also need to show the possibility of . Consider an execution where all processes have either crashed before outputting, or picked 1 at line 4 or line 8, yielding the output set .

A.4 Synchronous Binary Consensus Algorithm (Line 10)

The algorithm of this section (Algorithm 6) addresses the Sync case of line 10 in Table 2. Every process pP starts by executing the communication step of the first synchronous round (lines 2 and 3). They first pick a pseudo-random value v from the set {0,1} at line 2, and communicate a propose(v) information at line 3. Then, every pP moves to the computation step of the first synchronous round (lines 4 and 5). At this stage, we can show that all non-crashed processes see the same set of propose(v) information. Process p output 0 if it has observed any propose(0) information during round 1 (line 4), otherwise, p output 1 (line 5).

Let us remark that this algorithm only requires a single round of 𝖼𝗈𝗆𝗆𝗎𝗇𝗂𝖼𝖺𝗍𝖾/𝗈𝖻𝗌𝖾𝗋𝗏𝖾 communication to terminate. To the familiar reader, this fact may seem incompatible with the well-known result stating that, in synchronous message-passing systems, consensus requires at least t+1 communication rounds (where t is the maximum number of crashes) [1]. However, this apparent contradiction stems from the fact that, in a synchronous message-passing system, one round at the 𝖼𝗈𝗆𝗆𝗎𝗇𝗂𝖼𝖺𝗍𝖾/𝗈𝖻𝗌𝖾𝗋𝗏𝖾 level may comprise up to t+1 rounds at the 𝗌𝖾𝗇𝖽/𝗋𝖾𝖼𝖾𝗂𝗏𝖾 level. This can be intuitively understood by considering that reliable broadcast, which is used to implement 𝖼𝗈𝗆𝗆𝗎𝗇𝗂𝖼𝖺𝗍𝖾/𝗈𝖻𝗌𝖾𝗋𝗏𝖾 in message-passing networks, also requires t+1 rounds to terminate [11]. This is, in particular, needed to guarantee that all processes correctly receive the sender’s message despite the potential crashes.

Theorem 19.

Under Sync and 0t<n1, Algorithm 6 implements the set of output sets O={{0},{1}}.

Proof.

Under Sync and 0t<n1, there is at least nt1 correct processes. The safety of Algorithm 6 is proved in the following.

  • Impossibility of . Any correct process p necessarily outputs a value at line 4 or line 5, therefore is impossible.

  • Impossibility of {0,1}. Let us denote by PobsP the set of processes that observe some output(v) at the end of round 1. By C-Synchrony, all processes in Pobs must have observed the same set of propose(v) communicated at the beginning of round 1, and they must have therefore taken the same branch at line 4 or line 5, thus the output cannot contain 2 distinct values.

Algorithm 6 Synchronous algorithm for the Sync case of line 10 of Table 2, assuming t<n1.

The completeness of Algorithm 6 is proved in the following.

  • Possibility of {0}. There is an execution where a process p picks value v=0 at line 2, communicates output(0) at line 3, and observes its own output(0) and outputs 0 at line 4. By the impossibility of {0,1}, this execution will produce output set {0}.

  • Possibility of {1}. Let us denote by PcomP the set of processes that communicate some output(v) at the beginning of round 1. There is an execution where all processes in Pcom have picked value v=1 at line 2, and therefore communicate propose(1) at line 3. By C-Local-Termination, C-Global-Termination, and C-Synchrony, any process p must observe only propose(1) information at the end of round 1, and it must therefore output 1 at line 5. By the impossibility of {0,1}, this execution will produce output set {1}.