From a380daff168cccac72b716294cc6cd947d9e0df6 Mon Sep 17 00:00:00 2001
From: Matt Corallo <git@bluematt.me>
Date: Thu, 8 Sep 2016 10:43:22 -0400
Subject: Switch priority order to highest-first and add sample negotiation

---
 bip-0152.mediawiki | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

(limited to 'bip-0152.mediawiki')

diff --git a/bip-0152.mediawiki b/bip-0152.mediawiki
index 9a01165..5635ed3 100644
--- a/bip-0152.mediawiki
+++ b/bip-0152.mediawiki
@@ -139,13 +139,20 @@ A new inv type (MSG_CMPCT_BLOCK == 4) and several new protocol messages are adde
 
 ==Protocol Versioning==
 # The protocol version negotiation allows two nodes to agree on the version of compact blocks which they will exchange. As it is only in a single field, it does not allow a node to support a specific version in only one direction (sending or receiving).
-# Upon connection establishment, a node SHOULD send a burst of sendcmpct messages containing every version of compact block encodings for which they are willing to support sending cmpctblock and blocktxn messages, and receiving getblocktxn messages. These messages SHOULD be ordered in the order of the priority which the node wishes to receive cmpctblock/blocktxn messages, with the highest-priority version sendcmpct message sent last.
-# The encoding version used to send a cmpctblock or blocktxn message or to receive a getblocktxn message MUST be the second integer (version number) in the most recent sendcmpct message received for which a sendcmpct message with the same version number was sent.
+# Upon connection establishment, a node SHOULD send a burst of sendcmpct messages containing every version of compact block encodings for which they are willing to support sending cmpctblock and blocktxn messages, and receiving getblocktxn messages. These messages SHOULD be ordered in the order of the priority which the node wishes to receive cmpctblock/blocktxn messages, with the highest-priority version sendcmpct message sent first.
+# The encoding version used to send a cmpctblock or blocktxn message or to receive a getblocktxn message MUST be the second integer (version number) in the first sendcmpct message received for which a sendcmpct message with the same version number was sent.
 # Nodes MUST NOT send a sendcmpct message which contains a version number other than the version number which has been negotiated for receiving cmpctblock/blocktxn messages after sending a request for a MSG_CMPCT_BLOCK object, sending a cmpctblock, getblocktxn, blocktxn, or pong message.
-# Nodes MUST NOT set the first integer (boolean) value in sendcmpct messages to 1 in any sendcmpct message prior to the last sendcmpct message which contains a novel second integer (version number).
-# As a node must send all sendcmpct messages which contain a novel version announcement before any other compact block-related messages, it is possible to determine which version of compact blocks will be used for each object received. It is, however, not possible to know which version will be used to encode the response to a request for a compact block object before any MSG_CMPCT_BLOCK-containing inv, cmpctblock, getblocktxn, blocktxn, or ping messages have been exchanged.
+# As a node must send all sendcmpct messages which contain a novel version announcement before any other compact block-related messages, it is possible to determine which version of compact blocks will be used for each object received. It is, however, not possible to know which version will be used to encode the response to a request for a compact block object before any MSG_CMPCT_BLOCK-containing inv, cmpctblock, getblocktxn, blocktxn, or ping/pong messages have been exchanged.
 # Thus, if a node wishes to determine exactly which version of compact blocks will be used before requesting a compact block object, it must send all of its sendcmpct version announcements, followed by a ping, and wait for the pong response to ensure it has received all sendcmpctblock version announcement messages from the remote peer. Nodes can, obviously, however, determine that the version used will be at least a certain version (in their priority order) after having received a sendcmpct message from the remote peer containing that version as the second integer.
 
+===Sample Version Implementation===
+# By way of example, an implementation of the above protocol might look like the following.
+# Upon exchanging version/verack messages, a node immediately sends its list of sendcmpct announcements to the other side, with the version which it wants to receive sent first.
+# Upon receiving the first sendcmpct announcement with a protocol version which is understood from the remote peer, a node will "lock in" the compact block encoding version which will be used to encode compact blocks to that peer.
+# Upon receiving a sendcmpct announcement with a protocol version which is understood from the remote peer, a node will check if that protocol version is higher-receive-priority than the current receive-protocol-version in use on the connection, and switch to that version for decoding new compact block messages received.
+# A node might wish to keep a flag for each peer which indicates compact block version negotiation is complete, which can be set upon receiving any compact block-related, or pong message.
+# The above implementation requires only a compile-time list of supported versions in some static priority order, two version fields per peer, and an optional negotiation-complete boolean per-peer.
+
 ==Specification for version 2==
 Compact blocks version 2 is almost identical to version 1, but supports segregated witness transactions (BIP 141 and BIP 144). The changes are:
 
-- 
cgit v1.2.3

