278 lines
17 KiB
TeX
278 lines
17 KiB
TeX
|
|
\subsection{Model extension}
|
|
We consider a static set of $n$ processes with known identities, communicating by reliable point-to-point channels, in a complete graph. Messages are uniquely identifiable.
|
|
|
|
\paragraph{Synchrony.} The network is asynchronous. Processes may crash or be byzantine.
|
|
|
|
\paragraph{Communication.} Processes can exchange through a Reliable Broadcast (\RB) object (defined below) which is invoked with the functions \RBcast$(m)$ and \RBreceived$()$. There exists $n$ shared object called DenyList (\DL) (defined below) that is interfaced with the functions \APPEND$(x)$, \PROVE$(x)$ and \READ$()$.
|
|
|
|
\paragraph{Byzantine behaviour}
|
|
A process is said to exhibit Byzantine behaviour if it deviates arbitrarily from the prescribed algorithm. Such deviations may, for instance, consist in invoking primitives (\RBcast, \APPEND, \PROVE, etc.) with invalid inputs or inputs crafted maliciously, colluding with other Byzantine processes in an attempt to manipulate the system state or violate its guarantees, deliberately delaying or accelerating the delivery of messages to selected nodes so as to disrupt the expected timing of operations, or withholding messages and responses in order to induce inconsistencies in the system state.
|
|
|
|
Byzantine processes are constrained by the following. They cannot forge valid cryptographic signatures or threshold shares without access to the corresponding private keys. They cannot violate the termination, validity, or anti-flickering properties of the \DL{} object. They also cannot break the integrity, no-duplicates, or validity properties of the \RB{} primitive.
|
|
|
|
|
|
\paragraph{Notation.} Let $\Pi$ be the finite set of process identifiers. Two authorization subsets are $M \subseteq \Pi$ (processes allowed to issue \APPEND) and $V \subseteq \Pi$ (processes allowed to issue \PROVE). Indice $i \in \Pi$ refer to processes, and $p_i$ denotes the process with identifier $i$. Let $\mathcal{M}$ denote the universe of uniquely identifiable messages, with $m \in \mathcal{M}$. Let $\mathcal{R} \subseteq \mathbb{N}$ be the set of round identifiers; we write $r \in \mathcal{R}$ for a round. We use the precedence relation $\prec_k$ for the $\DL_k$ linearization: $x \prec_k y$ means that operation $x$ appears strictly before $y$ in the linearized history of $\DL_k$. For any finite set $A \subseteq \mathcal{M}$, \ordered$(A)$ returns a deterministic total order over $A$ (e.g., lexicographic order on $(\textit{senderId},\textit{messageId})$ or on message hashes). For any round $r \in \mathcal{R}$, define $\Winners_r^i \triangleq \{\, j \in \Pi \mid (j,\PROVEtrace(r)) \prec_k \APPEND(r) \,\}$, i.e., the set of processes whose $\PROVE(r)$ appears before the first $\APPEND(r)$ in the $\DL_k$ linearization. By extension for the set $X$ which contains every $\DL$ we define $\Winners_r \triangleq \bigcup_{k \in X} \Winners_r^k$.
|
|
We denoted by $\PROVE^{(j)}(r)$ or $\APPEND^{(j)}(r)$ the operation $\PROVE(r)$ or $\APPEND(r)$ invoked by process $j$, and by $\PROVE^{(j)}_{(k)}(r)$ or $\APPEND^{(j)}_{(k)}(r)$ the same operation invoked on the $\DL_k$ object.
|
|
|
|
% ------------------------------------------------------------------------------
|
|
\subsection{Primitives}
|
|
|
|
\subsubsection{t-BFT-DL}
|
|
|
|
We consider a t-Byzantine Fault Tolerant DenyList (t-$\BFTDL$) with the following properties.
|
|
There are 3 operations : $\BFTPROVE(x), \BFTAPPEND(x), \BFTREAD(x)$ such that :
|
|
|
|
\paragraph{Termination.} Every operation $\BFTAPPEND(x)$, $\BFTPROVE(x)$, and $\BFTREAD()$ invoked by a correct process always returns.
|
|
|
|
\paragraph{PROVE Validity.} The invocation of $op = \BFTPROVE(x)$ by a correct process is valid iff there exist a set of correct process $C$ such that $\forall c \in C$, $c$ invoke $op_2 = \BFTAPPEND(x)$ with $op_2 \prec op_1$ and $|C| \leq t$
|
|
|
|
\paragraph{PROVE Anti-Flickering.} If the invocation of a operation $op = \BFTPROVE(x)$ by a correct process $p \in \Pi_V$ is invalid, then any $\BFTPROVE(x)$ operation that appears after $op$ in $\Seq$ is invalid.
|
|
|
|
\paragraph{READ Liveness.} Let $op = \BFTREAD()$ invoke by a correct process such that $R$ is the result of $op$. For all $(i, \PROVEtrace(x)) \in R$ there exist a valid invocation of $\BFTPROVE(x)$ by $p_i$.
|
|
|
|
\paragraph{READ Anti-Flickering.} Let $op_1, op_2$ two $\BFTREAD()$ operations that returns respectively $R_1, R_2$. Iff $op_1 \prec op_2$ then $R_2 \subseteq R_1$. Otherwise $R_1 \subseteq R_2$.
|
|
|
|
\paragraph{READ Safety.} Let $op_1, op_2$ respectively a valid $\BFTPROVE(x)$ operation submited by the process $p_i$ and a $\BFTREAD()$ operation submited by any correct process such that $op_1 \prec op_2$. Let $R$ the result of $op_2$ then $R \ni (i, \PROVEtrace(x))$
|
|
|
|
\subsection{DL $\Rightarrow$ t-BFT-DL}
|
|
|
|
|
|
Fix $3t < |M|$. Let
|
|
\[
|
|
\mathcal{U} = \{\, U \subseteq M \mid |U| = |M| - t \,\}.
|
|
\]
|
|
For each $U \in \mathcal{U}$, we instantiate one DenyList object $DL_U$ whose authorization sets are
|
|
\[
|
|
\Pi_M(DL_T) = S_T = U
|
|
\qquad\text{and}\qquad
|
|
\Pi_V(DL_T) = V.
|
|
\]
|
|
|
|
\[
|
|
|\mathcal{U}| = \binom{|M|}{|M| - t}.
|
|
\]
|
|
|
|
\begin{algorithmic}[1]
|
|
|
|
% \renewcommand{\algletter}{}
|
|
\begin{algorithm}[H]
|
|
\caption{t-BFT-DL implementation using multiple DL objects}
|
|
|
|
% \caption{\BFTAPPEND}
|
|
\Function{$\BFTAPPEND$}{x}
|
|
\For{\textbf{each } $U \in \mathcal{U}$ st $i \in U$}
|
|
\State $DL_U.\APPEND(x)$
|
|
\EndFor
|
|
\EndFunction
|
|
|
|
\vspace{1em}
|
|
|
|
% \caption{\BFTPROVE}
|
|
\Function{$\BFTPROVE$}{x}
|
|
\State $state \gets false$
|
|
\For{\textbf{each } $U \in \mathcal{U}$}
|
|
\State $state \gets state \textbf{ OR } DL_U.\PROVE(x)$
|
|
\EndFor
|
|
\State \Return $state$
|
|
\EndFunction
|
|
|
|
\vspace{1em}
|
|
|
|
% \caption{\BFTREAD}
|
|
\Function{$\BFTREAD$}{$\bot$}
|
|
\State $results \gets \emptyset$
|
|
\For{\textbf{each } $U \in \mathcal{U}$}
|
|
\State $results \gets results \cup DL_U.\READ()$
|
|
\EndFor
|
|
\State \Return $results$
|
|
\EndFunction
|
|
\end{algorithm}
|
|
\end{algorithmic}
|
|
|
|
\begin{lemma}[BFT-PROVE Validity]
|
|
The invocation of $op = \BFTPROVE(x)$ by a correct process is invalid iff there exist at least $t+1$ distinct processes in $M$ that invoked a valid $\BFTAPPEND(x)$ before $op$ in $\Seq$.
|
|
\end{lemma}
|
|
|
|
\begin{proof}
|
|
Let $op=\BFTPROVE(x)$ be an invocation by a correct process $p_i$. Let $A\subseteq M$ be the set of distinct issuers that invoked $\BFTAPPEND(x)$ before $op$ in $\Seq$.
|
|
|
|
\begin{itemize}
|
|
\item \textbf{Case (i): $|A|\ge t+1$.}
|
|
Fix any $U\in\mathcal{U}$. $A\cap U\neq\emptyset$. Pick $j\in A\cap U$. Since $j\in U$, the call $\BFTAPPEND^{(j)}(x)$ triggers $DL_U.\APPEND(x)$, and because $\BFTAPPEND^{(j)}(x)\prec op$ in $\Seq$, this induces a valid $DL_U.\APPEND(x)$ that appears before the induced $DL_U.\PROVE(x)$ by $p_i$. By \textbf{PROVE Validity} of $\DL$, the induced $DL_U.\PROVE(x)$ is invalid. As this holds for every $U\in\mathcal{U}$, there is \emph{no} component $DL_U$ where $\PROVE(x)$ is valid, so the field $state$ at line DL9 is never becoming true, and $op$ return false.
|
|
|
|
\item \textbf{Case (ii): $|A|\le t$.}
|
|
There exists $U^\star\in\mathcal{U}$ such that $A\cap U^\star=\emptyset$. For any $j\in A$, we have $j\notin U^\star$, so $\BFTAPPEND^{(j)}(x)$ does \emph{not} call $DL_{U^\star}.\APPEND(x)$. Hence no valid $DL_{U^\star}.\APPEND(x)$ appears before the induced $DL_{U^\star}.\PROVE(x)$. Since also $i\in \Pi_V(DL_{U^\star})$, by \textbf{PROVE Validity} of $\DL$ the induced $DL_{U^\star}.\PROVE(x)$ is valid. Therefore, there exists a component with a valid $\PROVE(x)$, so $op$ is valid.
|
|
\end{itemize}
|
|
|
|
\smallskip
|
|
Combining the cases yields the claimed characterization of invalidity.
|
|
\end{proof}
|
|
|
|
\begin{lemma}[BFT-PROVE Anti-Flickering]
|
|
If the invocation of a operation $op = \BFTPROVE(x)$ by a correct process $p \in \Pi_V$ is invalid, then any $\BFTPROVE(x)$ operation that appears after $op$ in $\Seq$ is invalid.
|
|
\end{lemma}
|
|
|
|
\begin{proof}
|
|
Let $op=\BFTPROVE(x)$ be an invocation by a correct process $p_i$ that is \emph{invalid} in $\Seq$.
|
|
By BFT-PROVE Validity, this implies that there exist at least $t+1$ \emph{distinct} processes in $M$ that invoked a \emph{valid} $\BFTAPPEND(x)$ before $op$ in $\Seq$. Let $A\subseteq M$ denote that set, with $|A|\ge t+1$.
|
|
|
|
Fix any $U\in\mathcal{U}$. We have $A\cap U\neq\emptyset$. Pick $j\in A\cap U$. Since $j\in U$, the call $\BFTAPPEND^{(j)}(x)$ triggers a call $DL_U.\APPEND(x)$. Moreover, because $\BFTAPPEND^{(j)}(x)\prec op$ in $\Seq$, the induced $DL_U.\APPEND(x)$ appears before the induced $DL_U.\PROVE(x)$ of $op$ in the projection $\Seq_U$.
|
|
|
|
Hence, in $\Seq_U$, there exists a \emph{valid} $DL_U.\APPEND(x)$ that appears before the $DL_U.\PROVE(x)$ induced by $op$. By \textbf{PROVE Validity} the base $\DL$ object, the induced $DL_U.\PROVE(x)$ is therefore \emph{invalid} in $\Seq_U$.
|
|
|
|
Let $op'=\BFTPROVE(x)$ be any invocation such that $op\prec op'$ in $\Seq$. Fix again any $U\in\mathcal{U}$. Hence, the $DL_U.\PROVE(x)$ induced by $op'$ appears after the $DL_U.\PROVE(x)$ induced by $op$ in $\Seq_U$. Since the induced $DL_U.\PROVE(x)$ of $op$ is invalid, by \textbf{PROVE Anti-Flickering} of $\DL$, \emph{every} subsequent $DL_U.\PROVE(x)$ in $\Seq_U$ is invalid.
|
|
|
|
As this holds for every $U\in\mathcal{U}$, there is no component $DL_U$ in which the induced $\PROVE(x)$ of $op'$ is valid.
|
|
\end{proof}
|
|
|
|
\begin{lemma}[READ Liveness]
|
|
Let $op = \BFTREAD()$ invoke by a correct process such that $R$ is the result of $op$. For all $(i, \PROVEtrace(x)) \in R$ there exist a valid invocation of $\BFTPROVE(x)$ by $p_i$.
|
|
\end{lemma}
|
|
|
|
\begin{proof}
|
|
Let $R$ the result of a $READ()$ operation submit by any correct process. $(i, \PROVEtrace(x)) \in R$ implie that $\exists U^\star \in \mathcal{U}$ such that $(i, \PROVEtrace(x)) \in R^{U^\star}$ with $R^{U^\star}$ the result of $DL_{U^\star}.\READ()$. By \textbf{READ Validity} $(i, \PROVEtrace(x)) \in R^{U^\star}$ implie that there exist a valid $DL_{U^\star}.\PROVE^{(i)}(x)$. The for loop in the $\BFTPROVE(x)$ implementation return true iff there at least one valid $DL_{U}.\PROVE^{(i)}(x)$ for any $U \in \mathcal{U}$.
|
|
|
|
Hence because there exist a $U^\star$ such that $DL_{U^\star}.\PROVE^{(i)}(x)$, there exist a valid $\BFTPROVE^{(i)}(x)$.
|
|
|
|
$(i, \PROVEtrace(x)) \in R \implies \exists \BFTPROVE^{(i)}(x)$
|
|
\end{proof}
|
|
|
|
\begin{lemma}[READ Anti-Flickering]
|
|
Let $op_1, op_2$ two $\BFTREAD()$ operations that returns respectively $R_1, R_2$. Iff $op_1 \prec op_2$ then $R_2 \subseteq R_1$. Otherwise $R_1 \subseteq R_2$.
|
|
\end{lemma}
|
|
|
|
\begin{proof}
|
|
Let $R_1, R_2$ respectively the output of two $\BFTREAD()$ operations $op_1, op_2$ such that $op_1 \prec op_2$.
|
|
By the implementation of $\BFTREAD$, $R_k = \bigcup_{U \in \mathcal{U}} R_k^U$ where $R_k^U$ is the result of $DL_U.\READ()$ during $op_k$.
|
|
|
|
Because $op_1 \prec op_2$ for any $U \in \mathcal{U}$, the $DL_U.\READ()$ induced by $op_1$ happen before the $DL_U.\READ()$ induced by $op_2$. Hence we have for all $U, R_2^U \subseteq R_1^U$.
|
|
Therefore
|
|
\[
|
|
\bigcup_U R_2^U \subseteq \bigcup_U R_1^U \implies
|
|
R_2 \subseteq R_1
|
|
\]
|
|
\end{proof}
|
|
|
|
\begin{lemma}[READ Safety]
|
|
Let $op_1, op_2$ respectively a valid $\BFTPROVE(x)$ operation submited by the process $p_i$ and a $\BFTREAD()$ operation submited by any correct process such that $op_1 \prec op_2$. Let $R$ the result of $op_2$ then $R \ni (i, \PROVEtrace(x))$
|
|
\end{lemma}
|
|
|
|
\begin{proof}
|
|
Let $op_1 = \BFTPROVE^{(i)}(x)$ be a valid operation by a correct process $p_i$ and $op_2 = \BFTREAD()$ be any $\BFTREAD()$ operation such that $op_1 \prec op_2$ in $\Seq$.
|
|
By BFT-PROVE Validity, there exist at most $t$ distinct processes in $M$ that invoked a valid $\BFTAPPEND(x)$ before $op_1$ in $\Seq$. Let $A\subseteq M$ denote that set, with $|A|\le t$.
|
|
|
|
There exists $U^\star\in\mathcal{U}$ such that $A\cap U^\star=\emptyset$. For any $j\in A$, we have $j\notin U^\star$, so $\BFTAPPEND^{(j)}(x)$ does \emph{not} call $DL_{U^\star}.\APPEND(x)$. Hence no valid $DL_{U^\star}.\APPEND(x)$ appears before the induced $DL_{U^\star}.\PROVE(x)$ of $op_1$. Since also $i\in \Pi_V(DL_{U^\star})$, by \textbf{PROVE Validity} of $\DL$ the induced $DL_{U^\star}.\PROVE^{(i)}(x)$ is valid.
|
|
|
|
Now, because $op_1 \prec op_2$ in $\Seq$, the induced $DL_{U^\star}.\PROVE^{(i)}(x)$ appears before the induced $DL_{U^\star}.\READ()$ of $op_2$ in $\Seq_{U^\star}$. By \textbf{READ Safety} of $\DL$, the result $R^{U^\star}$ of the induced $DL_{U^\star}.\READ()$ contains $(i, \PROVEtrace(x))$.
|
|
|
|
Finally, by the implementation of $\BFTREAD()$, we have $R = \bigcup_{U \in \mathcal{U}} R^U$, so $(i, \PROVEtrace(x)) \in R$.
|
|
\end{proof}
|
|
|
|
\begin{theorem}
|
|
For any fixed value $t$ such that $3t < |M|$, multiple DenyList Object can be used to implement a t-Byzantine Fault Tolerant DenyList Object.
|
|
\end{theorem}
|
|
|
|
\begin{proof}
|
|
Follows directly from the previous lemmas.
|
|
\end{proof}
|
|
|
|
\subsection{Algorithm}
|
|
|
|
\subsubsection{Variables}
|
|
Each process $p_i$ maintains the following local variables:
|
|
\begin{algorithmic}
|
|
\State $\current \gets 0$
|
|
\State $\received \gets \emptyset$
|
|
\State $\delivered \gets \emptyset$
|
|
\State $\prop[r][j] \gets \bot, \forall r, j$
|
|
\State $W_r \gets \bot, \forall r$
|
|
\State $\resolved[r] \gets \bot, \forall r$
|
|
\State $Y[j]$ \Comment{Set of $n$ \BFTDL{}}
|
|
\end{algorithmic}
|
|
|
|
\renewcommand{\algletter}{D}
|
|
\begin{algorithm}[H]
|
|
\caption{ABroadcast$(m)$}
|
|
\begin{algorithmic}[1]
|
|
\Function{ABroadcast}{$m$}
|
|
% \State $r \gets \current$
|
|
\State $S \gets (\received \cup \{m\})$
|
|
\For{\textbf{each}\ $r \in \{\current, \current +1, \dots\}$}
|
|
\Statex \Comment{PROPOSAL PHASE}
|
|
\State $\RBcast(i, \texttt{PROP}, S, r)$
|
|
\State \textbf{wait} until $|W_r| \geq n - f$ where $W_r \gets \{j: (j, \PROVEtrace(x)) \in \bigcup_{k \in \Pi} Y[k].\BFTREAD()\}$
|
|
\Statex \Comment{COMMIT PHASE}
|
|
\State \textbf{for each} $j \in W_r$ \textbf{do} $Y[j].\BFTAPPEND(r)$
|
|
\State $\RBcast(i, \texttt{COMMIT}, r)$
|
|
\State \textbf{wait} until $|\resolved[r]| \geq n - f$
|
|
\Statex \Comment{X PHASE}
|
|
\State $W_r \gets \{j: (j, \PROVEtrace(x)) \in \bigcup_{k \in \Pi} Y[k].\BFTREAD()\}$
|
|
\If{$\exists r' \in \mathcal{R}, j \in W_{r'} : m \in \prop[r'][j]$} \Comment{any process $j$ submited $m$ in any round $r'$}
|
|
\State \textbf{break}
|
|
\EndIf
|
|
\EndFor
|
|
\EndFunction
|
|
\end{algorithmic}
|
|
\end{algorithm}
|
|
|
|
\renewcommand{\algletter}{C}
|
|
\begin{algorithm}[H]
|
|
\caption{ADeliver$(m)$}
|
|
\begin{algorithmic}[1]
|
|
\Function{ADeliver}{m}
|
|
\State $r \gets \current$
|
|
\If{$|\resolved[r]| < n - f$}
|
|
\State \Return $\bot$
|
|
\EndIf
|
|
\State $W_r \gets \{j: (j, \PROVEtrace(x)) \in \bigcup_{k \in \Pi} Y[k].\BFTREAD()\}$
|
|
\If{$\exists j \in W_r,\ \prop[r][j] = \bot$}
|
|
\State \Return $\bot$
|
|
\EndIf
|
|
\State $M_r \gets \bigcup_{j \in W_r} \prop[r][j]$
|
|
\State $m \gets \ordered(M_r \setminus \delivered)[0]$ \Comment{Set $m$ as the smaller message not already delivered}
|
|
\State $\delivered \leftarrow \delivered \cup \{m\}$
|
|
\If{$M_r \setminus \delivered = \emptyset$} \Comment{Check if all messages from round $r$ have been delivered}
|
|
\State $\current \leftarrow \current + 1$
|
|
\EndIf
|
|
\State \textbf{return} $m$
|
|
\EndFunction
|
|
\end{algorithmic}
|
|
\end{algorithm}
|
|
|
|
\renewcommand{\algletter}{E}
|
|
\begin{algorithm}[H]
|
|
\caption{RB handlers}
|
|
\begin{algorithmic}[1]
|
|
\Upon{$Rdeliver(j, \texttt{PROP}, S, r)$}
|
|
\State $\received \gets \received \cup \{S\}$
|
|
\State $\prop[r][j] \gets S$
|
|
\State $Y[j].\BFTPROVE(r)$
|
|
\EndUpon
|
|
|
|
\vspace{1em}
|
|
|
|
\Upon{$Rdeliver(j, \texttt{COMMIT}, r)}$
|
|
\State $\resolved[r] \gets \resolved[r] \cup \{j\}$
|
|
\EndUpon
|
|
\end{algorithmic}
|
|
\end{algorithm}
|
|
|
|
\begin{definition}[BFT Closed round for $i$]
|
|
Given $Seq^{(i)}$ the linearization of the $\BFTDL$ $Y[i]$, a round $r \in \mathcal{R}$ is \emph{closed} in $\Seq$ iff there exist at least $n - f$ distinct processes $j \in \Pi$ such that $\BFTAPPEND^{(j)}(r)$ appears in $\Seq^{(i)}$.
|
|
\end{definition}
|
|
|
|
\begin{definition}[BFT Closed round]
|
|
A round $r \in \mathcal{R}$ is \emph{closed} iff for all process $p_i$, $r$ is closed in $\Seq^{(i)}$.
|
|
\end{definition}
|
|
|
|
\subsection{Proof of correctness}
|
|
|
|
\begin{lemma}[BFT Stable round closure]
|
|
% If a round $r$ is closed by a correct process,
|
|
\end{lemma}
|
|
|
|
\begin{theorem}
|
|
The algorithm implements a BFT Atomic Reliable Broadcast.
|
|
\end{theorem}
|