diff --git a/src/Hydra/Protocol/Figures/head-protocol-states.tex b/src/Hydra/Protocol/Figures/head-protocol-states.tex index 9a1e729..e2ac029 100644 --- a/src/Hydra/Protocol/Figures/head-protocol-states.tex +++ b/src/Hydra/Protocol/Figures/head-protocol-states.tex @@ -21,7 +21,8 @@ \path[->] (open) edge [bend left=20] node {$\stClose$} (closed); \path[->] (open) edge [loop above] node {$\mathsf{increment}$} (open); \path[->] (open) edge [loop below] node {$\mathsf{decrement}$} (open); - \path[->] (closed) edge [bend left=20] node {$\stFanout$} (final); + \path[->] (closed) edge [bend left=20] node {\textcolor{red}{$\stFanout$ (complete)}} (final); + \path[->] (closed) edge [loop right] node {\textcolor{red}{$\stFanout$ (partial)}} (closed); \path[->] (closed) edge [loop above] node {$\stContest$} (closed); \path[->] (initial) edge [bend right=20] node {$\stAbort$} (final); \end{tikzpicture} diff --git a/src/Hydra/Protocol/Figures/offchain-protocol.tex b/src/Hydra/Protocol/Figures/offchain-protocol.tex index f810ab4..87f88b0 100644 --- a/src/Hydra/Protocol/Figures/offchain-protocol.tex +++ b/src/Hydra/Protocol/Figures/offchain-protocol.tex @@ -48,7 +48,7 @@ $\Uinit \gets \bigcup_{j=1}^{n} U_j$ \; % $\Out~(\hpSnap,(0,U_0))$ \; $\hatmL \gets \Uinit$ \; - $\bar{\mc S} \gets \Sno(0, 0, [], \Uinit, \emptyset , \emptyset)$ \; + $\bar{\mc S} \gets \Sno(0, 0, [], \Uinit, \emptyset , \emptyset, \textcolor{red}{\accUTxO(\Uinit)})$ \; $\hatv, \hats \gets 0$ \; $\hatmT \gets \emptyset$ \; $\tx_\omega \gets \bot$ \; @@ -129,9 +129,9 @@ $U \gets U_{\mathsf{active}} \applytx \underline{\tx}_{\mathsf{req}}$ \; $\hats \gets s$ \; % TODO: DRY message creation - $\eta \gets \combine(U)$ \; - $\eta_\alpha \gets \mathsf{combine}(U_\alpha)$ \; - $\eta_\omega \gets \mathsf{combine}(\mathsf{outputs}(\tx_\omega))$ \; + \textcolor{red}{$\eta \gets \accUTxO(U)$} \; + \textcolor{red}{$\eta_\alpha \gets \accUTxO(U_\alpha)$} \; + \textcolor{red}{$\eta_\omega \gets \accUTxO(\mathsf{outputs}(\tx_\omega))$} \; $\msSig_i \gets \msSign(\hydraSigningKey, (\cid || v || \hats || \eta || \eta_\alpha || \eta_\omega))$ \; % TODO: use a seen snapshot to keep track of things easier $\hatSigma \gets \emptyset$ \; @@ -165,17 +165,18 @@ $\msCSig \gets \msComb(\hydraKeys^{setup}, \hatSigma)$ \; % TODO: DRY message creation - $\eta \gets \combine(\hatmU)$ \; + \textcolor{red}{$A \gets \bar{\mc S}.A$} \; + \textcolor{red}{$\eta \gets \bar{\mc S}.U$} \; - $\eta_\alpha \gets \mathsf{combine}(U_\alpha)$ \; + \textcolor{red}{$\eta_\alpha \gets \bar{\mc S}.U_\alpha$} \; $U_\omega \gets \mathsf{outputs}(\tx_\omega)$ \; - $\eta_\omega \gets \mathsf{combine}(U_\omega)$ \; + \textcolor{red}{$\eta_\omega \gets \bar{\mc S}.U_\omega$} \; % NOTE: Implementation differs here and % below as it stores seen version in seen % snapshot and uses that to verify \Req{} $\msVfy(\hydraKeysAgg, (\cid || \hatv || \hats || \eta || \eta_\alpha || \eta_\omega), \msCSig)$ \; % create confirmed snapshot for later reference - $\bar{\mc S} \gets \Sno(\hatv, \hats, \hatmT, \hatmU, U_\alpha, U_\omega)$ \; + $\bar{\mc S} \gets \Sno(\hatv, \hats, \hatmT, \hatmU, U_\alpha, U_\omega, \bar{\mc S}.A)$ \; $\bar{\mc S}.\sigma \gets \msCSig$ \; %$\Out~(\hpSnap,(\bar{\mc S}.s,\bar{\mc S}.U))$ \; $\forall \tx \in \mT_{\mathsf{req}} : \Out (\hpConf,\tx)$ \; @@ -261,9 +262,9 @@ \begin{walgo}{0.6} % CLOSE from client \On{$(\hpClose)$ from client}{ - $\eta \gets \combine(\bar{\mc S}.U)$ \; - $\eta_\alpha \gets \combine(\bar{\mc S}.U_\alpha$) \; - $\eta_\omega \gets \combine(\bar{\mc S}.U_\omega)$ \; + \textcolor{red}{$\eta \gets \hash(\bar{\mc S}.A)$} \; + \textcolor{red}{$\eta_\alpha \gets \hash(\accUTxO(\bar{\mc S}.U_\alpha))$} \; + \textcolor{red}{$\eta_\omega \gets \hash(\accUTxO(\bar{\mc S}.U_\omega))$} \; $\xi \gets \bar{\mc S}.\sigma$ \; % XXX: \hatv needed to distinguish between CloseType redeemer, explain how exactly? $\PostTx{}~(\mtxClose, \hatv, \bar{\mc S}.v, \bar{\mc S}.s, \eta , \eta_\alpha, \eta_\omega, \xi)$ \; @@ -275,9 +276,9 @@ % CLOSE TX \On{$(\gcChainClose, \eta) \lor (\gcChainContest, s_{c}, \eta)$ from chain}{ \If{$\bar{\mc S}.s > s_{c}$}{ - $\eta \gets \combine(\bar{\mc S}.U)$ \; - $\eta_\alpha \gets \combine(\bar{\mc S}.U_\alpha$) \; - $\eta_\omega \gets \combine({\bar{\mc S}.U_\omega})$ \; + \textcolor{red}{$\eta \gets \hash(\bar{\mc S}.A)$} \; + \textcolor{red}{$\eta_\alpha \gets \hash(\accUTxO(\bar{\mc S}.U_\alpha))$} \; + \textcolor{red}{$\eta_\omega \gets \hash(\accUTxO(\bar{\mc S}.U_\omega))$} \; $\xi \gets \bar{\mc S}.\sigma$ \; % XXX: \hatv needed to distinguish between CloseType redeemer, explain how exactly? $\PostTx{}~(\mtxContest, \hatv, \bar{\mc S}.v, \bar{\mc S}.s, \eta , \eta_\alpha, \eta_\omega , \xi)$ \; diff --git a/src/Hydra/Protocol/OffChain.tex b/src/Hydra/Protocol/OffChain.tex index f9f2dc4..dc40482 100644 --- a/src/Hydra/Protocol/OffChain.tex +++ b/src/Hydra/Protocol/OffChain.tex @@ -7,8 +7,16 @@ \section{Off-Chain Protocol}\label{sec:offchain} full life-cycle of a Hydra head on-chain, this section completes the picture by defining how the protocol behaves off-chain and notably the relationship between on- and off-chain semantics. Participants of the protocol are also called Hydra -head members, parties or simply protocol actors. The protocol is specified as a -reactive system that processes three kinds of inputs: +head members, parties or simply protocol actors. + +\noindent \textcolor{red}{The off-chain protocol coordinates BLS accumulator operations (see Section~\ref{sec:bls-accumulators}) +for partial fanout support. When UTxO sets are too large for single transactions (see Section~\ref{sec:bls-accumulators} +for limits details), the off-chain protocol automatically falls back to partial distribution using +exclusion proofs, ensuring all UTxOs can be distributed across multiple transactions +while maintaining cryptographic integrity.} + +The protocol is specified as a reactive system that processes three kinds of inputs: + \begin{enumerate} \item On-chain protocol transactions as introduced in Section~\ref{sec:on-chain}, which are posted to the mainchain and can be @@ -23,8 +31,7 @@ \section{Off-Chain Protocol}\label{sec:offchain} \item $\mathtt{decrementTx}$: removes UTxO from an open head \item $\mathtt{closeTx}$: closes a head \item $\mathtt{contestTx}$: contests a closed head - % NOTE: fanout not mentioned because not needed in off-chain protocol - % description + \item \textcolor{red}{$\mathtt{fanoutTx}$: distributes UTxOs from a closed head (partial or complete)} \end{itemize} Also, a special input when time advanced on chain may be used: \begin{itemize} @@ -136,12 +143,13 @@ \subsection{Variables} $\bar{\mc S}.U$ & snapshotted UTxO set \\ \hline $\bar{\mc S}.U_\alpha$ & pending UTxO to increment \\ \hline $\bar{\mc S}.U_\omega$ & pending UTxO to decrement \\ \hline + \textcolor{red}{$\bar{\mc S}.A$} & \textcolor{red}{BLS accumulator of the UTxO set} \\ \hline $\bar{\mc S}.\sigma$ & multisignature \\ \hline \end{tabular} \end{center} \end{itemize} -where constructor $\text{snObj}(v, n, T, U, U_\alpha, U_\omega)$ initializes a +where constructor $\text{snObj}(v, n, T, U, U_\alpha, U_\omega, \textcolor{red}{A})$ initializes a new snapshot object with $\bar{\mathcal{S}}.\sigma = \emptyset$. \\ Additionally, deposit objects are created using @@ -184,7 +192,7 @@ \subsubsection{Initializing the head} $\hatv = 0$, as well as snapshot number $\hats = 0$. No deposit transaction $\tx_{\alpha} = \bot$ and no decrement transaction $\tx_{\omega} = \bot$ are pending, and the last confirmed snapshot is initialized accordingly -$\bar{\mc S} \gets \blue{\Sno(0, 0, [], \Uinit, \emptyset, \emptyset)}$. +$\bar{\mc S} \gets \blue{\Sno(0, 0, [], \Uinit, \emptyset, \emptyset, \accUTxO(\Uinit))}$. \subsubsection{Processing transactions off-chain} @@ -280,8 +288,8 @@ \subsubsection{Processing transactions off-chain} multisignature $\msCSig$ and $\Req$ it to be valid (constructing the signed message as in $\hpRS$). If everything is fine, the snapshot can be considered confirmed by creating the snapshot object -$\bar{\mc S} \gets \Sno(\hatv, \hats, \hatmT, \hatmU, U_{\alpha}, \mathsf{outputs}(\tx_{\omega}))$ -and storing the multi-signature $\msCSig$ in it for later reference. In case +$\bar{\mc S} \gets \Sno(\hatv, \hats, \hatmT, \hatmU, U_{\alpha}, \mathsf{outputs}(\tx_{\omega}), \textcolor{red}{A})$ +where \textcolor{red}{$A = \accUTxO(\hatmU)$ is the accumulator of the UTxO set}, and storing the multi-signature $\msCSig$ in it for later reference. In case there is a pending decommit, any participant can now submit a \mtxDecrement{} transaction by providing the just confirmed snapshot with its digests of the active UTxO set $\eta$ and the to be removed UTxO set $\eta_{\omega}$. If, however, there @@ -306,6 +314,16 @@ \subsubsection{Processing transactions off-chain} is incremented on each \mtxIncrement{} transaction as described in Section~\ref{sec:increment-tx} +\textcolor{red}{\dparagraph{$\mathtt{fanoutTx}$.}\quad Upon observing a \mtxFanout{} +transaction, the distributed UTxOs are removed from the local state tracking. +If this was a partial fanout (not all UTxOs were distributed), the head remains +in $\stClosed$ state with updated accumulator containing the remaining UTxOs. +If this was a complete fanout (all UTxOs distributed), the head transitions to +$\stFinal$ state. The off-chain protocol must coordinate partial fanout to +ensure proper selection of UTxO subsets and generation of exclusion proofs. +\todo{Add detailed off-chain protocol for partial fanout coordination, including +selection strategy for UTxO subsets.}} + \subsubsection{Closing the head} \dparagraph{$\hpClose$.}\quad In order to close a head, a client issues the @@ -388,6 +406,7 @@ \subsection{Rollbacks and protocol changes}\label{sec:rollbacks} \input{Hydra/Protocol/Figures/offchain-protocol} \todo{In figure: $\combine$ on UTxO slightly different than on commits} +\textcolor{red}{\todo{Update off-chain protocol to support partial fanout coordination}} %%% Local Variables: %%% mode: latex diff --git a/src/Hydra/Protocol/OnChain.tex b/src/Hydra/Protocol/OnChain.tex index a544431..af09996 100644 --- a/src/Hydra/Protocol/OnChain.tex +++ b/src/Hydra/Protocol/OnChain.tex @@ -1,9 +1,14 @@ \clearpage \section{On-chain Protocol}\label{sec:on-chain} \todo{Update figures} +\textcolor{red}{\todo{Update fanoutTx.svg figure to show partial fanout concept - either complete distribution or partial distribution with remaining UTxOs}} \todo{Open problem: ensure abort is always possible. e.g. by individual aborts or undoing commits} \todo{Open problem: ensure fanout is always possible, e.g. by limiting complexity of $U_0$} +\textcolor{red}{\todo{Update UTxO set digest mechanism to support partial fanout when transaction size limits are exceeded}} +\textcolor{red}{\todo{Update combine function: change from simple hash to commitment scheme that supports partial distribution proofs}} +\textcolor{red}{\todo{Implement fallback mechanism: try full fanout first, fall back to partial fanout if transaction size limit exceeded}} +\textcolor{red}{\todo{Consider transaction chaining for seamless partial fanout execution}} \noindent The following sections describe the the \emph{on-chain} protocol controlling the life-cycle of a Hydra head, which can be intuitively described @@ -12,6 +17,13 @@ \section{On-chain Protocol}\label{sec:on-chain} protocol transaction on-chain: \mtxInit{}~\ref{sec:init-tx}, \mtxCom{}~\ref{sec:commit-tx}, \mtxAbort{}~\ref{sec:abort-tx}, \mtxCollect{}~\ref{sec:collect-tx}, \mtxIncrement{}~\ref{sec:increment-tx}, \mtxDecrement{}~\ref{sec:decrement-tx}, \mtxClose{}~\ref{sec:close-tx}, \mtxContest{}~\ref{sec:contest-tx}, and \mtxFanout{}~\ref{sec:fanout-tx}. \\ +\noindent \textcolor{red}{The protocol uses BLS accumulators (see Section~\ref{sec:bls-accumulators}) to enable +partial fanout when UTxO sets exceed transaction size limits (see Section~\ref{sec:bls-accumulators} +for limits details). The \mtxCollect{} transaction +creates BLS accumulator commitments to UTxO sets, and \mtxFanout{} transactions use +exclusion proofs to distribute subsets of UTxOs while maintaining cryptographic guarantees +about the remaining UTxOs.} \\ + \noindent Besides the main state transitions of the head protocol, there is the related ``deposit protocol'' with two transactions in support of \mtxIncrement{}: \mtxDeposit{}~\ref{sec:deposit-tx} and \mtxRecover{}~\ref{sec:recover-tx}. \\ @@ -235,6 +247,7 @@ \subsection{Abort Transaction}\label{sec:abort-tx} \[ \hash(\bigoplus_{j=1}^{m} \bytes(o_{j})) = \combine([C_{i} ~ | ~ \forall [1 \dots |\hydraKeys|], C_{i} \neq \bot]) \] + \textcolor{red}{\todo{Update abort transaction to support partial distribution when all commits together are too big for a single transaction}} \item Transaction is signed by a participant $\exists \{\cid \mapsto \keyHash_{i} \mapsto -1\} \in \txMint \Rightarrow \keyHash_{i} \in \txKeys$. \item All tokens are burnt @@ -279,13 +292,13 @@ \subsection{CollectCom Transaction}\label{sec:collect-tx} \] where $n = |\hydraKeys|$ and \[ - \combine(\underline{C}) = \hash(\mathsf{concat}({\sortOn(1, \mathsf{concat}(\underline{C}))}^{\downarrow2})) + \combine(\underline{C}) = \textcolor{red}{\accUTxO}(\mathsf{concat}({\sortOn(1, \mathsf{concat}(\underline{C}))}^{\downarrow2})) \] - That is, given a list of committed UTxO $\underline{C}$, where each element is + \textcolor{red}{That is, given a list of committed UTxO $\underline{C}$, where each element is a list of output references and the serialised representation of what was committed, $\combine$ first concatenates all commits together, sorts this list - by the output references, concatenates all bytes and hashes the - result\footnote{Sorting is required to ensure a canonical representation which + by the output references, and creates a commitment to the UTxO set that supports + partial fanout}\footnote{Sorting is required to ensure a canonical representation which can also be reproduced from the UTxO set later in the fanout.}. \item All committed value captured and no value is extracted @@ -393,8 +406,9 @@ \subsection{Recover Transaction}\label{sec:recover-tx} comparing hashes of serialised representations of the $m$ recovering outputs $o_{1} \dots o_{m}$ with the canonically combined committed UTxOs in $C$: \[ - \hash(\bigoplus_{j=1}^{m} \bytes(o_{j})) = \hash(\mathsf{concat}({\sortOn(1, C)}^{\downarrow2})) + \hash(\bigoplus_{j=1}^{m} \bytes(o_{j})) = \textcolor{red}{\combine(C)} \] + \textcolor{red}{\todo{Consider partial recovery for deposit transactions when fractional deposits allow multiple UTxO and some are too small to recover individually}} \item Transaction is posted after the deadline \[ \txValidityMin > t_{\mathsf{recover}} @@ -465,8 +479,9 @@ \subsection{Increment Transaction}\label{sec:increment-tx} where $\eta_\alpha$ is the digest of all deposited UTxO in $C$ sorted by their output references \[ - \eta_\alpha = \hash(\mathsf{concat}({\sortOn(1, C)}^{\downarrow2})) + \textcolor{red}{\eta_\alpha = \combine(C)} \] + \textcolor{red}{\todo{Update increment transaction to support partial distribution if needed}} \item The value in the head output is increased accordingly \[ \valHead \cup \valDeposit = \valHead' @@ -519,8 +534,9 @@ \subsection{Decrement Transaction}\label{sec:decrement-tx} \] where $\eta_\omega$ is the digest of all removed UTxO \[ - \eta_\omega = \hash(\bigoplus_{j=2}^{m+1} \bytes(o_{j})) + \textcolor{red}{\eta_\omega = \accUTxO(\bigoplus_{j=2}^{m+1} \bytes(o_{j}))} \] + \textcolor{red}{\todo{Consider partial distribution for decrement transactions when the withdrawal set is too big for a single transaction}} \item The value in the head output is decreased accordingly \[ \valHead' \cup (\bigcup_{j=2}^{m+1} \val_{j}) = \valHead @@ -812,51 +828,59 @@ \subsection{Contest Transaction}\label{sec:contest-tx} \subsection{Fan-Out Transaction}\label{sec:fanout-tx} -Once the contestation phase is over, a head may be finalized by posting a -\mtxFanout{} transaction (see Figure~\ref{fig:fanoutTx}), which -distributes UTxOs from the head according to the latest state. It consists of +\textcolor{red}{Once the contestation phase is over, a head may be finalized by posting one or more +\mtxFanout{} transactions (see Figure~\ref{fig:fanoutTx}), which +distribute UTxOs from the head according to the latest state. The protocol first attempts +a complete fanout of all UTxOs. If this fails due to transaction size limits (see Section~\ref{sec:bls-accumulators} +for limits details), it automatically falls back to partial fanout, distributing a subset of UTxOs and proving the remaining UTxOs +are still valid. A fanout transaction consists of} \begin{itemize} - \item one input spending from $\nuHead$ holding the $\st$, and - \item outputs $o_{1} \dots o_{m+n+n'}$ to distribute UTxOs. + \item \textcolor{red}{one input spending from $\nuHead$ holding the $\st$, and} + \item \textcolor{red}{outputs $o_{1} \dots o_{m+n+n'}$ to distribute a subset of UTxOs.} \end{itemize} -Note that \mtxFanout{} represents a final transition of the state machine and -hence there is no state machine output. +\textcolor{red}{Note that \mtxFanout{} may represent either a final transition of the state machine +(when all UTxOs are distributed) or an intermediate transition (when only a subset +is distributed). In the latter case, the state machine remains in $\stClosed$ state +with updated accumulator containing the remaining UTxOs.} \begin{figure} \centering \includesvg[width=0.8\textwidth]{Hydra/Protocol/Figures/fanoutTx.svg} \caption{\mtxFanout{} transaction spending the $\stClosed$ head output and - distributing funds with outputs $o_{1} \dots o_{m+n+n'}$.}\label{fig:fanoutTx} + distributing funds with outputs $o_{1} \dots o_{m+n+n'}$. \textcolor{red}{The transaction can + distribute either all UTxOs (complete fanout) or a subset (partial fanout) with + proofs that remaining UTxOs are still valid.}}\label{fig:fanoutTx} \end{figure} \noindent The state-machine validator $\nuHead$ is spent with -$\redeemerHead = (\mathsf{fanout}, m, n, n')$, where $m$, $n$ and $n'$ are -outputs to distribute from the $\stClosed$ state, and checks: +\textcolor{red}{$\redeemerHead = (\mathsf{fanout}, m, n, n', \pi_{\eta}, \pi_{\alpha\Delta}, \pi_{\omega\Delta}, \eta'_{remaining})$}, where: +\begin{itemize} + \item $m$, $n$ and $n'$ are outputs to distribute from the $\stClosed$ state + \item \textcolor{red}{$\pi_{\eta}$, $\pi_{\alpha\Delta}$, $\pi_{\omega\Delta}$ are partial distribution proofs for the distributed UTxO sets} + \item \textcolor{red}{$\eta'_{remaining}$ is the updated commitment containing remaining UTxOs} +\end{itemize} +The validator checks: \begin{menumerate} - \item State is advanced from $\datumHead \sim \stClosed$ to terminal state - $\stFinal$: % XXX: What does this actually mean? + \item \textcolor{red}{State transition: If all UTxOs are distributed, transition to $\stFinal$; otherwise remain in $\stClosed$ with updated accumulator:} \[ - (\stClosed,\cid,\hydraKeys,\Tcontest,v, s,\eta,\eta_\alpha\Delta,\eta_\omega\Delta,\contesters,\tfinal) \xrightarrow[m,n,n']{\stFanout} \stFinal + \textcolor{red}{(\stClosed,\cid,\hydraKeys,\Tcontest,v, s,\eta,\eta_\alpha\Delta,\eta_\omega\Delta,\contesters,\tfinal) \xrightarrow[m,n,n',\pi_{\eta},\pi_{\alpha\Delta},\pi_{\omega\Delta}]{\stFanout} \stFinal \text{ or } \stClosed'} \] - \item The first $m$ outputs are distributing funds according to $\eta$. That is, - the outputs exactly correspond to the UTxO canonically combined $U^{\#}$ (see - Section~\ref{sec:collect-tx}): + \item \textcolor{red}{The first $m$ outputs are distributing a subset of funds according to $\eta$. The exclusion proof $\pi_{\eta}$ proves that the distributed outputs $S_{\eta} = \{o_1, \ldots, o_m\}$ can be removed from accumulator $\eta$:} \[ - \eta = U^{\#} = \hash(\bigoplus_{j=1}^{m} \bytes(o_{j})) + \textcolor{red}{\accVerifyPartial(\eta, S_{\eta}, \pi_{\eta}) = \true} \] - \item The following $n$ outputs are distributing funds according to - $\eta_\alpha\Delta$. That is, the outputs exactly correspond to the UTxO canonically - combined $U^{\#}_{\alpha\Delta}$ (see Section~\ref{sec:collect-tx}): + \item \textcolor{red}{The following $n$ outputs are distributing a subset of funds according to + $\eta_\alpha\Delta$. The exclusion proof $\pi_{\alpha\Delta}$ proves that the distributed outputs $S_{\alpha\Delta} = \{o_{m+1}, \ldots, o_{m+n}\}$ can be removed from accumulator $\eta_{\alpha\Delta}$:} \[ - \eta_{\alpha\Delta} = U^{\#}_{\alpha\Delta} = \hash(\bigoplus_{j=m}^{m+n} \bytes(o_{j})) + \textcolor{red}{\accVerifyPartial(\eta_{\alpha\Delta}, S_{\alpha\Delta}, \pi_{\alpha\Delta}) = \true} \] - \item The next $n'$ outputs are distributing funds according to - $\eta_\omega\Delta$. That is, the outputs exactly correspond to the UTxO canonically - combined $U^{\#}_{\omega\Delta}$ (see Section~\ref{sec:collect-tx}): + \item \textcolor{red}{The next $n'$ outputs are distributing a subset of funds according to + $\eta_\omega\Delta$. The exclusion proof $\pi_{\omega\Delta}$ proves that the distributed outputs $S_{\omega\Delta} = \{o_{m+n+1}, \ldots, o_{m+n+n'}\}$ can be removed from accumulator $\eta_{\omega\Delta}$:} \[ - \eta_{\omega\Delta} = U^{\#}_{\omega\Delta} = \hash(\bigoplus_{j=m'}^{m+n'} \bytes(o_{j})) + \textcolor{red}{\accVerifyPartial(\eta_{\omega\Delta}, S_{\omega\Delta}, \pi_{\omega\Delta}) = \true} \] + \item \textcolor{red}{If not all UTxOs are distributed, the remaining accumulator $\eta'_{remaining}$ is correctly computed by removing the distributed UTxOs from the original accumulators.} \item Transaction is posted after contestation deadline $\txValidityMin > \tfinal$. \item All tokens are burnt $|\{\cid \mapsto \cdot \mapsto -1\} \in \txMint| = n + 1$. diff --git a/src/Hydra/Protocol/Preliminaries.tex b/src/Hydra/Protocol/Preliminaries.tex index b34ad9c..93c972e 100644 --- a/src/Hydra/Protocol/Preliminaries.tex +++ b/src/Hydra/Protocol/Preliminaries.tex @@ -37,6 +37,7 @@ \subsection{Notation} \item $\concat : \tyBytes^* \to \tyBytes$ is concatenating bytes, we also use operator $\bigoplus$ for this \item $\hash : x \to \tyBytes$ denotes a collision-resistant hashing function and $x^{\#}$ indicates the hash of $x$ + \textcolor{red}{\todo{Update hash function usage to support partial fanout where needed}} \item $\bytes : x \to \tyBytes$ denotes an invertible serialisation function mapping arbitrary data to bytes \item $a || b = \concat(\bytes(a), \bytes(b))$ is an operator which concatenates the $\bytes(b)$ to the $\bytes(a)$ @@ -83,6 +84,52 @@ \subsection{Public key multi-signature scheme}\label{sec:multisig} out the $ver$ suffix for verification key such that $k = k^{ver}$ for better readability. +\subsection{\textcolor{red}{BLS Accumulators for Partial Fanout}}\label{sec:bls-accumulators} + +\textcolor{red}{\noindent To enable partial fanout when UTxO sets are too large for a single transaction, +the protocol uses BLS (Boneh-Lynn-Shacham) accumulators~\cite{BLS2001,acc2018} that support partial distribution +proofs. This allows distributing a subset of UTxOs while proving that the remaining +UTxOs are still valid and can be distributed in subsequent transactions.} + +\textcolor{red}{\noindent A UTxO set is considered too large for a single transaction when one or more of the following +conditions occur:} +\begin{itemize} + \item \textcolor{red}{\textbf{Number of outputs:} The UTxO set contains more outputs than can fit in a single + transaction. On Cardano, this limit is typically around 80 ada-only outputs for fanout transactions.} + \item \textcolor{red}{\textbf{Total transaction size:} The serialized representation of all outputs, including + their values, addresses, and datums, exceeds the maximum transaction size limit (e.g., 16KB on Cardano).} + \item \textcolor{red}{\textbf{Asset complexity:} UTxOs containing many native assets or complex token structures + increase the transaction size beyond acceptable limits.} + \item \textcolor{red}{\textbf{Script references:} Large or numerous script references in outputs contribute to + transaction size limits.} +\end{itemize} + +\begin{definition}[\textcolor{red}{BLS Accumulator}] +\textcolor{red}{A BLS accumulator scheme provides the following operations:} +\begin{itemize} + \item \textcolor{red}{$\accSetup$ generates public parameters for the accumulator system} + \item \textcolor{red}{$\accCommit(U)$ creates a commitment to a UTxO set $U$} + \item \textcolor{red}{$\accWitness(C, u)$ generates a membership witness for UTxO $u$ in commitment $C$} + \item \textcolor{red}{$\accVerify(C, u, w)$ verifies that witness $w$ proves $u$ is in commitment $C$} + \item \textcolor{red}{$\accExclude(C, S)$ generates an exclusion proof for subset $S$ from commitment $C$} + \item \textcolor{red}{$\accVerifyExclude(C, S, \pi)$ verifies that exclusion proof $\pi$ allows removal of $S$ from $C$} +\end{itemize} +\end{definition} + +\begin{definition}[\textcolor{red}{Partial Distribution}] +\textcolor{red}{For a UTxO set $U$ and a subset $S \subseteq U$ to be distributed:} +\begin{itemize} + \item \textcolor{red}{$\accUTxO(U)$ creates a BLS accumulator commitment to the UTxO set $U$} + \item \textcolor{red}{$\accPartial(U, S)$ creates an exclusion proof showing that subset $S$ can be distributed} + \item \textcolor{red}{$\accVerifyPartial(C, S, \pi)$ verifies that exclusion proof $\pi$ allows distribution of $S$ from commitment $C$} +\end{itemize} +\end{definition} + +\textcolor{red}{\noindent The BLS accumulator enables the protocol to handle large UTxO sets by automatically falling back +to partial distribution when full fanout exceeds transaction size limits (as defined above). The accumulator provides +cryptographic guarantees that distributed UTxOs are valid and that remaining UTxOs are still +available for future distribution.} + \subsection{Extended UTxO}\label{sec:eutxo} The Hydra Head protocol is specified to work on the so-called Extended UTxO (EUTxO) ledgers like Cardano. diff --git a/src/macros.tex b/src/macros.tex index 78b58ea..5a2bb80 100644 --- a/src/macros.tex +++ b/src/macros.tex @@ -366,6 +366,17 @@ \newcommand{\sortOn}{\mathsf{sortOn}} \newcommand{\combine}{\mathsf{combine}} +% BLS Accumulator functions for partial fanout +\newcommand{\accSetup}{\mathsf{accSetup}} +\newcommand{\accCommit}{\mathsf{accCommit}} +\newcommand{\accWitness}{\mathsf{accWitness}} +\newcommand{\accVerify}{\mathsf{accVerify}} +\newcommand{\accExclude}{\mathsf{accExclude}} +\newcommand{\accVerifyExclude}{\mathsf{accVerifyExclude}} +\newcommand{\accUTxO}{\mathsf{accUTxO}} +\newcommand{\accPartial}{\mathsf{accPartial}} +\newcommand{\accVerifyPartial}{\mathsf{accVerifyPartial}} + \newcommand{\Txo}{\mathsf{txObj}} \newcommand{\Sno}{\mathsf{snObj}} \newcommand{\ApplyMax}{\mathsf{uApplyMax}} diff --git a/src/short.bib b/src/short.bib index 495628a..6447dab 100644 --- a/src/short.bib +++ b/src/short.bib @@ -120,3 +120,25 @@ @inproceedings{utxo-ma and Joachim and Zahnentferner}, year = 2020 } + +@article{BLS2001, + Author = {Dan Boneh and Ben Lynn and Hovav Shacham}, + Title = {Short Signatures from the Weil Pairing}, + Journal = {Journal of Cryptology}, + Volume = {17}, + Number = {4}, + Pages = {297--319}, + Year = {2004}, + Note = {Extended version of ASIACRYPT 2001}, + Doi = {10.1007/s00145-004-0314-9} +} + +@inproceedings{acc2018, + Author = {Benedikt B{\"u}nz and Stefano Chiesa and Pratyush Mishra and Nicholas Spooner}, + Title = {Recursive Proof Composition from Accumulation Schemes}, + Booktitle = {Theory of Cryptography}, + Pages = {401--430}, + Year = {2021}, + Note = {Universal accumulators for membership/exclusion proofs}, + Doi = {10.1007/978-3-030-90459-3_14} +}