# ZIP-317 transaction splitting
In [Zcash ZIP-317 (draft)](https://github.com/zcash/zips/pull/631) the [following formula](https://github.com/zcash/zips/pull/631/files#diff-25c7a2e2882ef10e0dddc86b7a276339eac6e57993a5f30866a773c4929df4b9R138) is proposed:
> base_fee + marginal_fee * max(0, inputs + outputs - grace_window_size)
## Arity-neutral parameters
We want the fee of issuing 1 large txn with $a$ inputs/outputs to be the same as the fees for $t$ transactions each with `grace_window_size` (or fewer) inputs/outputs. (See the following sections for rationale.)
This analysis _ignores_ any setup/overhead transaction costs, for example if a user has a single note/UTXO and they want to split out $t$ transactions to cover all their needed outputs, they might need preparatory transactions to split up that note, or they might need to chain change-outputs between their $t$ transactions.
Let's define short-hand variables to do some algebra, with protocol parameter constants ($B$, $M$, and $W$) upper case, and user/case-specific variables ($t$ and $a$) lower case:
- $B$ for $\mathrm{base\_fee} \ [\mathtt{ZAT}/\mathtt{TXN}]$
- $M$ for $\mathrm{marginal\_fee} \ [\mathtt{ZAT}/\mathtt{TXN}]$
- $W$ for $\mathrm{grace\_window\_size} \ [\mathtt{IO}]$
- $a \ [\mathtt{IO}]$ for the sum $\mathrm{inputs} + \mathrm{outputs}$ for either case of a single or many transactions. Assume $a \ge W$.
- $t \ [\mathtt{TXN}]$ is the number of transactions, each with $W$ or fewer inputs/outputs, so: $a \le t * W$
With these variables, the proposed formula looks like:
$$
B + M * \mathrm{max}(0, a-W)
$$
If the user issues a single transaction, it costs:
$$
B + M(a - W)
$$
OTOH, if they split it into $t$ transactions such that each transaction has $\le W$ IOs, that costs:
$$
tB
$$
Our goal is that either option costs the same, regardless of the size of $a$ and $t$:
$$
B + M(a - W) = tB
$$
For simplicity, assume $a = tW$. (In practice if $a < tW$, the some transactions will have fewer than $W$ IOs which costs the same as $W$ IOs, namely $B$ per transaction, so $tB$. If $a < tW$, the single transaction option would cost less than $tB$, which preserves the goal of not incentivizing transaction splitting.)
So:
$$
B + M(tW - W) = tB
$$
$$
B + tMW - MW = tB
$$
$$
B + (t-1)MW = tB
$$
We want to eliminate $t$ altogether, so that the two options cost the same regardless of the number of transactions:
$$
(t-1)MW = tB - B
$$
$$
(t-1)MW = B(t-1)
$$
$$
MW = B
$$
Summary: if $B = MW$ the cost to a user is the same whether they issues a single large transaction or many smaller transactions with the same number of IOs.
## Formula Rewrite
The ZIP draft defines the formula (written w/ our variable names) as:
$$
B + M * \mathrm{max}(0, a - W)
$$
When $B = MW$, this is equivalent to:
$$
\mathrm{max}(B, aM)
$$
We believe this second form is easier to understand, as well as to explain to users. Here's an example English user-facing description of the two forms:
- $B + M * \mathrm{max}(0, a - W)$ could be described as "Each transaction costs at least $B$, and if there are more than $W$ inputs and outputs, each one more than $W$ costs $M$."
- $\mathrm{max}(B, aM)$ could be described as "Each transaction costs $M$ for each input and output, with a minimum transaction fee of $B$."
### Equivalence Proof
As long as $B = MW$ the two forms are equivalent:
For the first form:
- when $a < W$:
- $B + M * \mathrm{max}(0, a - W)$
- $= B + M * 0$ because $a - W < 0$
- $= B$
- when $a \ge W$:
- $B + M * \mathrm{max}(0, a - W)$
- $= MW + M * \mathrm{max}(0, a - W)$ because $B = MW$
- $= MW + M * (a - W)$ because $a - W \ge 0$
- $= MW + aM - MW$
- $= aM$
For the second form $\mathrm{max}(B, aM)$:
- When $a \le W$:
- $\mathrm{max}(B, aM) = \mathrm{max}(B, \frac{a}{W} B)$ because $B = MW$
- $\frac{a}{W} \le 1$, so $\frac{a}{W} B \le B$
- $\mathrm{max}(B, \frac{a}{W} B)$
- $= B$
- When $a \ge W$:
- $\mathrm{max}(B, aM) = \mathrm{max}(WM, aM)$ because $B = WM$
- $\mathrm{max}(WM, aM) = aM$
(Note: this all relies on $W \ge 0$ which is implicitly true since its units are a number of items, inputs + outputs.)
## Do We Want To Incentivize More Smaller Transactions
Benefits:
- Transactions will have more similar arity so they're less distinguishable.
- Others?
Drawbacks:
- Users either have to do this by hand or else wallets will implement it for them. If the wallet doesn't do it, only "power users" will know how to reduce their fees.
- Issuing multiple txns is complicated:
- What if you need a shielded change note from a previous transaction? Now you have to wait for blocks between these transactions, slowing down your process.
- What if some transactions confirm while others are rolled back or otherwise fail to confirm? How do users track this and recover from it?
- The senders or recipients may have to examine multiple different block explorer pages to understand if the whole operation succeeded or not.
- Each transaction has overhead costs where each transaction is separately:
- relayed (thus adding network load and latency),
- validated,
- indexed (potentially adding performance issues to indexing),
- selected for block inclusion,
- tracked and displayed independently in wallets,
- etc…
So I lean towards no, and advocate for $W = 0$.
## Soapbox on Permissionlessness and Platform Neutrality
I believe it's really important in Zcash for us to avoid being "overly meddlesome" about usage patterns beyond concrete neutral security/economic issues.
We should aim for "platform neutrality": outside of direct security or economic concerns, we shouldn't try to distinguish which usage patterns we "like" or "don't like". If a usage pattern negatively impacts user experience, the appropriate solution is to improve performance or change costs to balance all usage patterns neutrally. This falls into security & economic concerns.
Second, even if we _did_ want to discriminate, we don't understand all usage and what needs it serves for current or future users.
For example, during the current "high output large transaction" performance problems I often hear people calling it an attack or spam. But _we don't know why users are doing this_!
People then make assumptions like "well, it's obviously harming network performance, so whoever is doing it is being malicious". But we _simply don't know_ why they are doing it, who they are, or what their awareness or background is. What if they don't speak English and are far removed from our circles? What if they aren't very technical and don't know their usage is a direct cause of the current performance issues? What if they never use mobile shielded wallets so they have no indication of mobile shielded scan performance issues?
What we _can_ say for certain is they are paying much less in fees than smaller transactions for the given performance load, and also we _can_ say for certain that our protocol stacks aren't up to the performance standards we need them to be for broader adoption. Let's focus on those platform neutral concerns that we can and should fix!