@@ -130,9 +130,29 @@ senderPaysFee pickUtxo feeOptions = go
130130 let fee = feeUpperBound feeOptions inps outs chgs
131131
132132 -- 2/
133- -- We try to cover fee with the available change by substracting equally
134- -- across all inputs. There's no fairness in that in the case of a
135- -- multi-account transaction. Everyone pays the same part.
133+ -- We lose the relationship between the transaction outputs and their
134+ -- corresponding inputs/change outputs here. This is a decision we
135+ -- may wish to revisit later. For now however note that since
136+ --
137+ -- (a) coin selection tries to establish a particular ratio
138+ -- between payment outputs and change outputs (currently it
139+ -- aims for an average of 1:1)
140+ --
141+ -- (b) coin selection currently only generates a single change
142+ -- output per payment output, distributing the fee
143+ -- proportionally across all change outputs is roughly
144+ -- equivalent to distributing it proportionally over the
145+ -- payment outputs (roughly, not exactly, because the 1:1
146+ -- proportion is best effort only, and may in some cases be
147+ -- wildly different).
148+ --
149+ -- Note that for (a) we don't need the ratio to be 1:1, the above
150+ -- reasoning will remain true for any proportion 1:n. For (b) however,
151+ -- if coin selection starts creating multiple outputs, and this number
152+ -- may vary, then losing the connection between outputs and change
153+ -- outputs will mean that that some outputs may pay a larger
154+ -- percentage of the fee (depending on how many change outputs the
155+ -- algorithm happened to choose).
136156 let (chgs', remainingFee) = reduceChangeOutputs fee chgs
137157 if getFee remainingFee == valueZero then
138158 -- 3.1/
@@ -176,7 +196,16 @@ coverRemainingFee pickUtxo fee = go emptySelection
176196 go (select io acc)
177197
178198
179- -- we should have (x + (sum ls) = sum result), but this check could overflow.
199+ -- Equally split the extra change obtained when picking new inputs across all
200+ -- other change. Note that, it may create an extra change output if:
201+ --
202+ -- (a) There's no change at all initially
203+ -- (b) Adding change to an exiting one would cause an overflow
204+ --
205+ -- It makes no attempt to divvy the new output proportionally over the change
206+ -- outputs. This means that if we happen to pick a very large UTxO entry, adding
207+ -- this evenly rather than proportionally might skew the payment:change ratio a
208+ -- lot. Could consider defining this in terms of divvy instead.
180209splitChange
181210 :: forall dom . (CoinSelDom dom )
182211 => Value dom
0 commit comments