The path is always the same. It’s just onion encryption, not onion routing. I don’t believe we would really gain anything by adding onion routing.
All filtering of outputs takes place on the trip from node1 to node3. node3 builds its kernel (kern3) from the sum of excesses for all included outputs.
Let’s step through an example with the 3 nodes and 4 outputs used in John’s description.
A. node1 has:
- C1_0
- C2_0
- C3_0
- C4_0
B. node1 calculates:
- C1_0 + x1_1 = C1_1
- C2_0 + x2_1 = C2_1
- C3_0 + x3_1 = C3_1
- C4_0 + x4_1 = C4_1
C. then passes them to node2 (sorting first). Let’s assume after sorting node2 gets:
- C2_1
- C4_1
- C1_1
- C3_1
D. node2 calculates:
- C2_1 + x2_2 = C2_2
- C4_1 + x4_2 = C4_2
- C1_1 + x1_2 = C1_2
- C3_1 + x3_2 = C3_2
E. then passes them to node3 (sorting first). Assume after sorting node3 gets:
- C3_2
- C4_2
- C2_2
- C1_2
F. node3 calculates the final outputs:
- C3_2 + x3_3 = C3_3
- C4_2 + x4_3 = C4_3
- C2_2 + x2_3 = C2_3
- C1_2 + x1_3 = C1_3
G. node3 finds that the rangeproofs for C3_3 and C2_3 are invalid, so removes them. That leaves:
- C4_3
- C1_3
H. node3 builds kernel kern3 using excesses from C4_3 and C1_3:
- kern3 - built using excess = x4_3 + x1_3
I. node3 sorts the final outputs. Let’s say that ends up [C1_3, C4_3]
. This is the transaction’s output list.
J. node3 sends node2:
- out =
[C1_3, C4_3]
- kerns =
[kern3]
- indices =
[2, 4]
K. node2 remembers what it sent in step (E), so indices [2,4]
means C4_2 and C1_2 were kept. It then builds kern2:
- kern2 - built using excess = x4_2 + x1_2
L. node2 remembers what it received from node1 in step (C), so translates the indices to get [2, 3]
M. node2 sends node1:
- out =
[C1_3, C4_3]
- kerns =
[kern2, kern3]
- indices =
[2, 3]
N. node1 remembers what it sent in step (C), so indices [2, 3]
means C4_1 and C1_1 were included. It builds kernel kern1:
- kern1 - built using excess = x4_1 + x1_1
O. node1 includes C4_0 and C1_0 as the inputs, giving a final transaction of:
- out =
[C1_3, C4_3]
- kerns =
[kern1, kern2, kern3]
- inputs =
[C1_0, C4_0]
Transaction offset not included here, but node1 can easily include that as part of kern1 creation in step (N).
It’s not easy to keep track of all of this. We could benefit from better notation. Hopefully I didn’t make any mistakes.