|
| 1 | + |
| 2 | +# Overview: Honest multiparty PayJoin |
| 3 | + |
| 4 | +The following is a concrete description of the honest multiparty PayJoin protocol. To understand why certain choices design were made, it is recommended to read the [overview document](./00_overview.md) first. |
| 5 | + |
| 6 | +## Motivation |
| 7 | + |
| 8 | +This protocol is best understood as a collaborative transaction construction protocol for mutually trusting parties. Its purpose is to let participants jointly build a transaction with potentially better privacy properties and cost savings than a unilateral construction. The other parties are not trusted with the safety of your funds. What they are trusted with is liveness (showing up, responding, and progressing the round) and privacy (handling protocol information honestly and not needlessly leaking it). |
| 9 | + |
| 10 | +## Roles |
| 11 | + |
| 12 | +### Initiator and Responder |
| 13 | + |
| 14 | +The Initiator signals willingness to batch to their counterparty over a bidirectional channel. This signal is conveyed by including the `mppj=1` parameter in the BIP21 URI. Either the BIP77 sender or receiver may be the Initiator. Parameters for their bi-directional channel may be encoded in the BIP21 (same as BIP77). |
| 15 | + |
| 16 | +The Responder is the counterparty who receives this signal. A Responder that does not support multiparty PayJoin will ignore the `mppj=1` parameter and proceed with standard BIP77. A Responder that supports it waits for a session to be created. |
| 17 | + |
| 18 | +Two timeouts govern the phase of the whole protocol: |
| 19 | + |
| 20 | +* `T_intent`: the duration both parties are willing to wait for a session to be created after the intent to batch is signaled. If no session is created within `T_intent`, both parties MUST fall back to standard BIP77 over their existing bidirectional channel. |
| 21 | +* `T_session`: the duration of the multiparty session itself, after which the session is considered expired. |
| 22 | + |
| 23 | +`T_session` is defined by the `SessionCreator` while `T_intent` is defined by the `Initiator`. |
| 24 | + |
| 25 | +// TODO: how do we indicate to sender/recv that we should join a mppj? out of band? New message? mailbox with more payment instructions? |
| 26 | + |
| 27 | +### SessionCreator |
| 28 | + |
| 29 | +Either the `Initiator` or the `Responder` may create the session. The party that does so is the `SessionCreator`. |
| 30 | +The `SessionCreator` is responsible to creating session parameters (defined below), bootstrapping the transport mechanism and disseminating session information to the rest of the peers to the best of their capabilities. `SessionCreator` holds no special authority once the session is live. They simply become a participant. |
| 31 | + |
| 32 | +### Participant |
| 33 | + |
| 34 | +Once a party joins a session they become a `Participant`. All participants share the same obligations as outlined below in the phases section. |
| 35 | + |
| 36 | +### Diagrams |
| 37 | + |
| 38 | +Single receiver, two senders. Receiver is `Initiator` for both senders and becomes the `SessionCreator`. |
| 39 | + |
| 40 | +```mermaid |
| 41 | +sequenceDiagram |
| 42 | + participant R as Receiver (Initiator) |
| 43 | + participant S1 as Sender 1 (Responder) |
| 44 | + participant S2 as Sender 2 (Responder) |
| 45 | +
|
| 46 | + R->>S1: BIP21 URI (mppj=1) |
| 47 | + R->>S2: BIP21 URI (mppj=1) |
| 48 | +
|
| 49 | + R->>S1: session invitation (s, session params) |
| 50 | + R->>S2: session invitation (s, session params) |
| 51 | +``` |
| 52 | + |
| 53 | +Sender 1 is the `Initiator` to the receiver who is an `Initiator` to sender 2. The receiver at time 3 becomes the `SessionCreator`. |
| 54 | + |
| 55 | +```mermaid |
| 56 | +sequenceDiagram |
| 57 | + participant S1 as Sender 1 (Initiator) |
| 58 | + participant R as Receiver (Responder / Initiator / SessionCreator) |
| 59 | + participant S2 as Sender 2 (Responder) |
| 60 | +
|
| 61 | + S1->>R: BIP21 URI (mppj=1) |
| 62 | + R->>S2: BIP21 URI (mppj=1) |
| 63 | +
|
| 64 | + R->>S1: session invitation (s, session params) |
| 65 | + R->>S2: session invitation (s, session params) |
| 66 | +``` |
| 67 | + |
| 68 | +## Session Parameters |
| 69 | + |
| 70 | +The SessionCreator fixes the following parameters before the session opens. All participants must verify that the final transaction conforms to the relevant parameters before signing. |
| 71 | + |
| 72 | +* **Global transaction fields**: `nLocktime`, `nVersion` |
| 73 | +* **Feerate**: each participant contributes fees proportional to the weight of their inputs and outputs |
| 74 | +* **Input constraints**: `nSequence`, script type, segwit only |
| 75 | +* **Timeout**: `T_session` (see Roles) |
| 76 | + |
| 77 | +## PSBT CRDT |
| 78 | + |
| 79 | +### Join Semantics |
| 80 | + |
| 81 | +Participants learn transaction fragments in arbitrary order and accumulate them as they arrive. In the honest setting there are no conflicting writes: global fields are fixed by the session parameters and each participant controls disjoint inputs and outputs. Any two valid fragments can therefore be merged by union. |
| 82 | + |
| 83 | +If the accumulated transaction does not balance, or any fragment violates the session parameters, a participant refuse to sign and abandon the session. |
| 84 | + |
| 85 | +// TODO: refer to nothingmuch's document |
| 86 | + |
| 87 | +## Communication model |
| 88 | + |
| 89 | +### Gossip broadcast over Iroh |
| 90 | + |
| 91 | +In the honest setting, participants can use an authenticated and encrypted gossip broadcast channel such as [Iroh gossip](https://docs.iroh.computer/connecting/gossip) to disseminate PSBT fragments. Each participant broadcasts their protocol messages (inputs, outputs, readiness declarations, and witnesses) to the session topic, and peers merge the received fragments into their local transaction view. |
| 92 | + |
| 93 | +This setting does not require transport-layer metadata privacy as a protocol requirement. The reason is that participants are already mutually trusted with privacy in the honest model, including trust not to retain or misuse linkability information learned during the session. As a result, unlike the [semi-honest](./semi-honest.md) setting, the protocol does not depend on anonymous transport primitives to maintain the intended privacy properties within the participant set. |
| 94 | + |
| 95 | +In this honest setting, a separate agreement protocol is not required for the success path. Gossip dissemination plus deterministic transaction construction is sufficient: if participants receive the same valid fragments, they converge to the same unsigned transaction. Any temporary view differences are primarily a liveness concern (delay or retry), not a fund-safety concern, because each participant still performs local validation and only signs an acceptable transaction. |
| 96 | + |
| 97 | +### Message Reconciliation |
| 98 | + |
| 99 | +Iroh gossip is a fire-and-forget dissemination mechanism. A peer that is offline or disconnected during the registration window will not receive messages broadcast while they were absent. When they reconnect, gossip provides no mechanism to recover missed messages. A peer with an incomplete view of the transaction will either construct the wrong unsigned transaction or fail to sign entirely. |
| 100 | + |
| 101 | +Reconciliation requires a persistent log that a rejoining peer can replay from a known index. |
| 102 | + |
| 103 | +With a trusted leader (RAFT-like protocol) |
| 104 | + |
| 105 | +A leader maintains a replicated log of all session messages. A peer that reconnects identifies the last log index it observed and requests all subsequent entries from the leader. This is the core log replication operation RAFT is designed for and requires no additional mechanism. The tradeoff is that the leader is trusted with liveness: if the leader is unavailable, reconciliation stalls. |
| 106 | + |
| 107 | +Without a trusted leader |
| 108 | + |
| 109 | +Each peer must retain the full session message log for the duration of the session and support explicit state sync requests from reconnecting peers. A reconnecting peer can detect gaps by comparing a content-addressed message set with a peer that stayed online. This approach distributes the liveness burden but requires peers to know what they are missing, which gossip does not provide by default. This would be a much larger engineering burden. |
| 110 | + |
| 111 | +Given that the honest model already accepts a trust assumption on liveness of a single peer, RAFT is the natural fit for this setting. The session creator can presumably become the RAFT leader. |
| 112 | +// TODO: how to do discovery of other peers? |
| 113 | + |
| 114 | +## Protocol Phases |
| 115 | + |
| 116 | +Input and output registration can be sent in any order. Ordering and sorting semantics must be defined a priori. |
| 117 | +// TODO: (Should outputs get defined before inputs ?) |
| 118 | +One possible definition is to use the hash of the protocol transcript as a salt to sort the inputs and outputs. |
| 119 | + |
| 120 | +All messages are base64 encoded as PSBT fragments. |
| 121 | + |
| 122 | +// TODO: coinselection strategy? do peers run their own coinselection based on their own target outputs? What if a recv doesnt have target outputs? Would peers change outputs based on others output selection? |
| 123 | + |
| 124 | +### Input Registration |
| 125 | + |
| 126 | +Each participant submits the transaction inputs they control. Inputs must be posted as independent messages. |
| 127 | +Global passive observers should not be able to determine which inputs originate from the same party. If the transport mechanism is encrypted this should not be an issue. |
| 128 | + |
| 129 | +### Psuedo Outputs |
| 130 | + |
| 131 | +// Move to semi-honest. In honest, peers can just declare how much they are burning in their input messages |
| 132 | + |
| 133 | +A pseudo output is an declaration of fee contribution above the session-mandated minimum. It participates in the balance equation like a real output but does not appear in the final transaction. Participants MUST post a pseudo output only when their intended fee contribution exceeds what the session parameters require. |
| 134 | + |
| 135 | +When the global sum of inputs minus outputs minus pseudo outputs reaches zero, every participant can independently verify the transaction is balanced and proceed declare Ready-to-sign. |
| 136 | + |
| 137 | +### Output Registration |
| 138 | + |
| 139 | +Output and pseudo output messages MUST carry a unique identifier to prevent double accounting. E.g a peer may read an output message multiple times. Since `TxOut`'s are not uniquely indentifiable that peer would have no ability to de-duplicate. |
| 140 | + |
| 141 | +A participant who wishes to back out of the session posts an output that causes the transaction balance to overflow. That is, their declared outputs exceed their input contribution. This makes the balance equation unsatisfiable and must cause all other participants to refuse to sign. |
| 142 | + |
| 143 | +### Ready-to-sign (RTS) declarations |
| 144 | + |
| 145 | +For each input they control, participants post a RTS declaration. This signals that they accept the current transaction template and are prepared to sign it. |
| 146 | +Only once all inputs have corresponding ready signals does the protocol advance. This ensures that all participants have finished contributing transaction fragments. |
| 147 | + |
| 148 | +When the global sum of inputs minus outputs minus pseudo outputs fee declarations hits zero, every participant can independently verify the transaction is balanced and sign. |
| 149 | + |
| 150 | +### Witness provision |
| 151 | + |
| 152 | +Participants provide witnesses for the inputs they control. Once all witnesses are available, any participant can assemble the fully signed transaction and broadcast it to the Bitcoin network. |
0 commit comments