algorithmpseudocode -> algorithm2e

This commit is contained in:
Amaury JOLY
2026-02-22 22:27:01 +01:00
parent 268c30a112
commit cc22c9d7f3
4 changed files with 262 additions and 245 deletions

View File

@@ -4,7 +4,7 @@ We consider a static set $\Pi$ of $n$ processes with known identities, communica
\paragraph{Synchrony.} The network is asynchronous.
\paragraph{Communication.} Processes can exchange through a Reliable Broadcast ($\RB$) primitive (defined below) which is invoked with the functions $\RBcast(m)$ and $m = \RBreceived()$. There exists a shared object called DenyList ($\DL$) (defined below) that is interfaced with a set $O$ of operations. There exist three types of these operations: $\APPEND(x)$, $\PROVE(x)$ and $\READ()$.
\paragraph{Communication.} Processes can exchange through a Reliable Broadcast ($\RB$) primitive (defined below) which is invoked with the functions $\RBcast(m)$ and $m = \RBreceived()$. There exists a shared object called DenyList ($\DL$) (defined below) that is interfaced with a set $O$ of operations. There exist three types of these operations: $\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.
@@ -53,42 +53,35 @@ For each $U \in \mathcal{U}$, we instantiate one DenyList object $DL_U$ whose au
|\mathcal{U}| = \binom{|M|}{|M| - t}.
\]
\begin{algorithmic}[1]
\begin{algorithm}
\caption{t-BFT-DL implementation using multiple DL objects}
% \renewcommand{\algletter}{}
\begin{algorithm}[H]
\caption{t-BFT-DL implementation using multiple DL objects}
\Fn{$\BFTAPPEND(x)$}{
\For{\textbf{each } $U \in \mathcal{U}$ st $i \in U$}{
$DL_U.\APPEND(x)$\;
}
}
% \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}
\vspace{1em}
\Fn{$\BFTPROVE(x)$}{
$state \gets false$\;
\For{\textbf{each } $U \in \mathcal{U}$}{
$state \gets state \textbf{ OR } DL_U.\PROVE(x)$\;\nllabel{code:prove-or}
}
\Return{$state$}\;
}
% \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}
\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}
\Fn{$\BFTREAD()$}{
$results \gets \emptyset$\;
\For{\textbf{each } $U \in \mathcal{U}$}{
$results \gets results \cup DL_U.\READ()$\;
}
\Return{$results$}\;
}
\end{algorithm}
\begin{lemma}[BFT-PROVE Validity]\label{lem: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$.
@@ -99,7 +92,7 @@ For each $U \in \mathcal{U}$, we instantiate one DenyList object $DL_U$ whose au
\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.
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~\ref{code:prove-or} 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.
@@ -181,94 +174,96 @@ For each $U \in \mathcal{U}$, we instantiate one DenyList object $DL_U$ whose au
\subsubsection{Variables}
Each process $p_i$ maintains the following local variables:
\begin{algorithmic}
% \State $\current \gets 0$
\State $\texttt{last\_commited} \gets 0$
\State $\texttt{last\_delivered} \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}
\LinesNotNumbered
\begin{algorithm}
$\texttt{last\_commited} \gets 0$\;
$\texttt{last\_delivered} \gets 0$\;
$\received \gets \emptyset$\;
$\delivered \gets \emptyset$\;
$\prop[r][j] \gets \bot, \forall r, j$\;
$W[r] \gets \bot, \forall r$\;
$\resolved[r] \gets \bot, \forall r$\;
$Y[j]$ a Set of $n$ $\BFTDL$\;
\end{algorithm}
\renewcommand{\algletter}{A}
\LinesNumbered
\begin{algorithm}[H]
% \caption{ABroadcast$(m)$}
\begin{algorithmic}[1]
\Function{ABroadcast}{$m$}
\State $\received \gets \received \cup \{m\}$
\State \Call{Propose}{}()
\EndFunction
\end{algorithmic}
\caption{$\ABbroadcast(m)$ at process $p_i$}\label{alg:broadcast-bft}
\SetAlgoLined
\Fn{ABroadcast($m$)}{
$\received \gets \received \cup \{m\}$\;
Propose()\;
}
\end{algorithm}
\renewcommand{\algletter}{B}
\begin{algorithm}[H]
\begin{algorithmic}[1]
\Statex \textbf{Proposer Job}
\Function{Propose}{$\bot$}
\State $r \gets \texttt{last\_commited}$
\While{$S \neq \emptyset$ with $S \gets \received \setminus (\delivered \cup (\bigcup_{r' < r} \bigcup_{j \in W[r']} \prop[r'][j]))$}
\Statex \Comment{PROP PHASE}
\State $\RBcast(i, \texttt{PROP}, S, \current)$
\State \textbf{wait} until $|\{j: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}| \geq n - f$
\Statex \Comment{COMMIT PHASE}
\State \textbf{for each} $j \in \Pi$ \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: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}$
\State $r \gets r + 1$
\EndWhile
\State $\texttt{last\_commited} \gets r$
\EndFunction
\end{algorithmic}
\caption{Propose($\bot$) at process $p_i$}\label{alg:propose-bft}
\SetAlgoLined
% \Statex \textbf{Proposer Job}
\Fn{Propose($\bot$)}{
$r \gets \texttt{last\_commited}$\;
\While{$S \neq \emptyset$ with $S \gets \received \setminus (\delivered \cup (\bigcup_{r' < r} \bigcup_{j \in W[r']} \prop[r'][j]))$}{
% \Comment{PROP PHASE}\;
\tcc*[f]{PROP PHASE}\\
$\RBcast(i, \texttt{PROP}, S, \current)$\;
\textbf{wait} until $|\{j: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}| \geq n - f$\;
% \Comment{COMMIT PHASE}
\tcc*[f]{COMMIT PHASE}\\
\textbf{for each} $j \in \Pi$ \textbf{do} $Y[j].\BFTAPPEND(r)$
$\RBcast(i, \texttt{COMMIT}, r)$\;
\textbf{wait} until $|\resolved[r]| \geq n - f$\;
% \Comment*{X PHASE}
\tcc*[f]{X PHASE}\\
$W[r] \gets \{j: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}$\;
$r \gets r + 1$\;
}
$\texttt{last\_commited} \gets r$\;
}
\end{algorithm}
\renewcommand{\algletter}{C}
% \renewcommand{\algletter}{C}
\begin{algorithm}[H]
% \caption*{ADeliver$(m)$}
\begin{algorithmic}[1]
\Function{ADeliver}{$\bot$}
\State $r \gets \texttt{last\_delivered}$
\If{$|\resolved[r]| < n - f$}
\State \Return $\bot$
\EndIf
\State $W[r] \gets \{j: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}$
\If{$\exists j \in W[r],\ \prop[r][j] = \bot$}
\State \Return $\bot$
\EndIf
\State $M \gets \bigcup_{j \in W[r]} \prop[r][j]$
\State $m \gets \ordered(M \setminus \delivered)[0]$ \Comment{Set $m$ as the smaller message not already delivered}
\State $\delivered \leftarrow \delivered \cup \{m\}$
\If{$M \setminus \delivered = \emptyset$} \Comment{Check if all messages from round $r$ have been delivered}
\State $\texttt{last\_delivered} \gets \texttt{last\_delivered} + 1$
\EndIf
\State \textbf{return} $m$
\EndFunction
\end{algorithmic}
\caption{$\ABdeliver()$ at process $p_i$}\label{alg:deliver-bft}
\SetAlgoLined
\Fn{ADeliver($\bot$)}{
$r \gets \texttt{last\_delivered}$\;
\If{$|\resolved[r]| < n - f$}{
\Return{$\bot$}
}
$W[r] \gets \{j: |\{k: (k, \PROVEtrace(r)) \in Y[j].\BFTREAD()\}| \geq t+1\}$\;
\If{$\exists j \in W[r],\ \prop[r][j] = \bot$}{
\Return{$\bot$}
}
$M \gets \bigcup_{j \in W[r]} \prop[r][j]$\;\nllabel{code:Mcompute}
$m \gets \ordered(M \setminus \delivered)[0]$\;
% \Comment*{Set $m$ as the smaller message not already delivered}
$\delivered \leftarrow \delivered \cup \{m\}$\;
\If{$M \setminus \delivered = \emptyset$}{
$\texttt{last\_delivered} \gets \texttt{last\_delivered} + 1$\;
}
% \Comment*{Check if all messages from round $r$ have been delivered}
\Return{$m$}
}
\end{algorithm}
\renewcommand{\algletter}{D}
% \renewcommand{\algletter}{D}
\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)$
\State \Call{Propose}{}()
\EndUpon
\caption{RB handler at process $p_i$}\label{alg:rb-handler-bft}
\SetAlgoLined
\Upon{$Rdeliver(j, \texttt{PROP}, S, r)$}{
$\received \gets \received \cup \{S\}$\;
$\prop[r][j] \gets S$\;
$Y[j].\BFTPROVE(r)$\;
Propose()\;
}
\vspace{1em}
\vspace{1em}
\Upon{$Rdeliver(j, \texttt{COMMIT}, r)}$
\State $\resolved[r] \gets \resolved[r] \cup \{j\}$
\EndUpon
\end{algorithmic}
\Upon{$Rdeliver(j, \texttt{COMMIT}, r)$}{
$\resolved[r] \gets \resolved[r] \cup \{j\}$\;
}
\end{algorithm}
\textbf{Everything below has to be updated}
@@ -292,7 +287,7 @@ Each process $p_i$ maintains the following local variables:
\end{proof}
\begin{lemma}[BFT Across rounds]\label{lem:bft-across-rounds}
For any $r, r'$ such that $r < r'$, if $r'$ is closed, $r$ is also closed.
For any $r, r'$ such that $r < r'$, if $r'$ is closed, $r$ is also closed.
\end{lemma}
\begin{proof}
@@ -302,7 +297,7 @@ Each process $p_i$ maintains the following local variables:
\end{proof}
\begin{lemma}[BFT Progress]\label{lem:bft_progress}
For any correct process $p_i$ such that
For any correct process $p_i$ such that
\[
\received \setminus (\delivered \cup (\cup_{r' < r} \cup_{j \in W[r'] \prop[r'][j]})) \neq \emptyset
\]
@@ -338,7 +333,7 @@ Each process $p_i$ maintains the following local variables:
\end{lemma}
\begin{lemma}[BFT EVentual proposal closure]\label{lem:bft-eventual-proposal-closure}
If a correct process $p_i$ define $M$ at line C10, then for every $j \in \Winners_r$, $\prop^{(i)}[r][j] \neq \bot$.
If a correct process $p_i$ define $M$ at line~\ref{code:Mcompute}, then for every $j \in \Winners_r$, $\prop^{(i)}[r][j] \neq \bot$.
\end{lemma}
\begin{lemma}[BFT Unique proposal per sender per round]\label{lem:bft-unique-proposal}