<oembed><type>rich</type><version>1.0</version><author_name>npub1j66aek8wm7jq8vaffs2l8w43evyywd4q7tcnqyge6xqezz0vcpks7jm42m</author_name><author_url>https://nostr.ae/npub1j66aek8wm7jq8vaffs2l8w43evyywd4q7tcnqyge6xqezz0vcpks7jm42m</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2016-05-07&#xA;📝 Original message:There was some confusion over the following email which was posted to the list&#xA;which appears to have been cancelled before a decision could be reached.&#xA;&#xA;Please note the email seems inflammatory in the &#34;acknowledgement&#34; section and&#xA;really should have been rewritten to contain specific details of the objection&#xA;and corrections expected.&#xA;&#xA;To be clear posts to the mailing list are either approved, or rejected for not&#xA;meeting the posting standards. This allows the author to make a quick correction&#xA;and resubmit. All rejections are cc&#39;d to&#xA;https://lists.ozlabs.org/pipermail/bitcoin-dev-moderation/&#xA;for transparency. Sometimes moderators get delayed - this week has been a busy&#xA;with lots of distractions one for everyone :)&#xA;&#xA;I&#39;m copying the entire message below:&#xA;&#xA;---------- Forwarded message ----------&#xA;From: Tom &lt;tomz at freedommail.ch&gt;&#xA;To: bitcoin-dev at lists.linuxfoundation.org, Matt Corallo&#xA;&lt;lf-lists at mattcorallo.com&gt;&#xA;Cc:&#xA;Date: Fri, 06 May 2016 13:31:15 +0100&#xA;Subject: Re: [bitcoin-dev] Compact Block Relay BIP&#xA;On Monday 02 May 2016 22:13:22 Matt Corallo via bitcoin-dev wrote:&#xA;&#xA;Thanks for putting in the time to make a spec!&#xA;&#xA;It looks good already, but I do think some more improvements can be made.&#xA;&#xA;&#xA;&gt; ===Intended Protocol Flow===&#xA;I&#39;m not a fan of the solution that a CNode should keep state and talk to&#xA;its remote nodes differently while announcing new blocks.&#xA;Its too complicated and ultimately counter-productive.&#xA;&#xA;The problem is that an individual node needs to predict network behaviour in&#xA;advance. With the downside that if it guesses wrong that both nodes end up&#xA;paying for the wrong guess.&#xA;This is not a good way to design a p2p layer.&#xA;&#xA;&#xA;&#xA;I would suggest that a new block is announced to all nodes equally and then&#xA;individual nodes can respond with a request of either a &#39;compact&#39; or a&#xA;normal block.&#xA;This is much more in line with the current design as well.&#xA;&#xA;Detection if remote nodes support compact blocks, for the purpose of&#xA;requesting a compact-block, can be done either via a network-bit or just a&#xA;protocol version. Or something else entirely, if you have better&#xA;suggestions.&#xA;&#xA;&#xA;&#xA;&gt; Variable-length integers: bytes are a MSB base-128 encoding of the&#xA;&gt; number.&#xA;&gt; The high bit in each byte signifies whether another digit follows.&#xA;&gt; [snip bitwise spec]&#xA;&#xA;I suggest just referring to UTF-8 which describes this just fine.&#xA;it is good practice to refer to existing specs when possible and not copy&#xA;the details.&#xA;&#xA;&gt; ====Short transaction IDs====&#xA;&gt; Short transaction IDs are used to represent a transaction without&#xA;&gt; sending a full 256-bit hash. They are calculated by:&#xA;&gt; # single-SHA256 hashing the block header with the nonce appended (in&#xA;&gt; little-endian)&#xA;&gt; # XORing each 8-byte chunk of the double-SHA256 transaction hash with&#xA;&gt; each corresponding 8-byte chunk of the hash from the previous step&#xA;&gt; # Adding each of the XORed 8-byte chunks together (in little-endian)&#xA;&gt; iteratively to find the short transaction ID&#xA;&#xA;I don&#39;t think this is needed. Just use the first 8 bytes.&#xA;The reason to do xor-ing doesn&#39;t hold up and extra complexity is unneeded.&#xA;Especially since you mention some lines down;&#xA;&#xA;&gt; The short transaction ID calculation is designed to take absolutely&#xA;&gt; minimal processing time during block compaction to avoid introducing&#xA;&gt; serious DoS vulnerabilities&#xA;&#xA;&#xA;==Acknowledgements==&#xA;&#xA;I think you need to acknowledge some more people, or just remove this&#xA;paragraph.&#xA;&#xA;Cheers&#xA;&#xA;&#xA;---------- Forwarded message ----------&#xA;From: bitcoin-dev-request at lists.linuxfoundation.org&#xA;To:&#xA;Cc:&#xA;Date: Fri, 06 May 2016 12:31:23 +0000&#xA;Subject: confirm 37d25406a07ab77823fba5f9b450438c410ccd75&#xA;If you reply to this message, keeping the Subject: header intact,&#xA;Mailman will discard the held message.  Do this if the message is&#xA;spam.  If you reply to this message and include an Approved: header&#xA;with the list password in it, the message will be approved for posting&#xA;to the list.  The Approved: header can also appear in the first line&#xA;of the body of the reply.&#xA;&#xA;&#xA;On Mon, May 2, 2016 at 3:13 PM, Matt Corallo via bitcoin-dev &lt;&#xA;bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&#xA;&gt; Hi all,&#xA;&gt;&#xA;&gt; The following is a BIP-formatted design spec for compact block relay&#xA;&gt; designed to limit on wire bytes during block relay. You can find the&#xA;&gt; latest version of this document at&#xA;&gt; https://github.com/TheBlueMatt/bips/blob/master/bip-TODO.mediawiki.&#xA;&gt;&#xA;&gt; There are several TODO items left on the document as indicated.&#xA;&gt; Additionally, the implementation linked at the bottom of the document&#xA;&gt; has a few remaining TODO items as well:&#xA;&gt;&#xA;&gt;  * Only request compact-block-announcement from one or two peers at a&#xA;&gt; time, as the spec requires.&#xA;&gt;  * Request new blocks using MSG_CMPCT_BLOCK where appropriate.&#xA;&gt;  * Fill prefilledtxn with more than just the coinbase, as noted by the&#xA;&gt; spec, up to 10K in transactions.&#xA;&gt;&#xA;&gt; Luke (CC&#39;d): Can you assign a BIP number?&#xA;&gt;&#xA;&gt; Thanks,&#xA;&gt; Matt&#xA;&gt;&#xA;&gt; &lt;pre&gt;&#xA;&gt;   BIP: TODO&#xA;&gt;   Title: Compact block relay&#xA;&gt;   Author: Matt Corallo &lt;bip at bluematt.me&gt;&#xA;&gt;   Status: Draft&#xA;&gt;   Type: Standards Track&#xA;&gt;   Created: 2016-04-27&#xA;&gt; &lt;/pre&gt;&#xA;&gt;&#xA;&gt; ==Abstract==&#xA;&gt;&#xA;&gt; Compact blocks on the wire as a way to save bandwidth for nodes on the&#xA;&gt; P2P network.&#xA;&gt;&#xA;&gt; The key words &#34;MUST&#34;, &#34;MUST NOT&#34;, &#34;REQUIRED&#34;, &#34;SHALL&#34;, &#34;SHALL NOT&#34;,&#xA;&gt; &#34;SHOULD&#34;, &#34;SHOULD NOT&#34;, &#34;RECOMMENDED&#34;, &#34;MAY&#34;, and &#34;OPTIONAL&#34; in this&#xA;&gt; document are to be interpreted as described in RFC 2119.&#xA;&gt;&#xA;&gt; ==Motivation==&#xA;&gt;&#xA;&gt; Historically, the Bitcoin P2P protocol has not been very bandwidth&#xA;&gt; efficient for block relay. Every transaction in a block is included when&#xA;&gt; relayed, even though a large number of the transactions in a given block&#xA;&gt; are already available to nodes before the block is relayed. This causes&#xA;&gt; moderate inbound bandwidth spikes for nodes when receiving blocks, but&#xA;&gt; can cause very significant outbound bandwidth spikes for some nodes&#xA;&gt; which receive a block before their peers. When such spikes occur, buffer&#xA;&gt; bloat can make consumer-grade internet connections temporarily unusable,&#xA;&gt; and can delay the relay of blocks to remote peers who may choose to wait&#xA;&gt; instead of redundantly requesting the same block from other, less&#xA;&gt; congested, peers.&#xA;&gt;&#xA;&gt; Thus, decreasing the bandwidth used during block relay is very useful&#xA;&gt; for many individuals running nodes.&#xA;&gt;&#xA;&gt; While the goal of this work is explicitly not to reduce block transfer&#xA;&gt; latency, it does, as a side effect reduce block transfer latencies in&#xA;&gt; some rather significant ways. Additionally, this work forms a foundation&#xA;&gt; for future work explicitly targeting low-latency block transfer.&#xA;&gt;&#xA;&gt; ==Specification==&#xA;&gt;&#xA;&gt; ===Intended Protocol Flow===&#xA;&gt; TODO: Diagrams&#xA;&gt;&#xA;&gt; The protocol is intended to be used in two ways, depending on the peers&#xA;&gt; and bandwidth available, as discussed [[#Implementation_Details|later]].&#xA;&gt; The &#34;high-bandwidth&#34; mode, which nodes may only enable for a few of&#xA;&gt; their peers, is enabled by setting the first boolean to 1 in a&#xA;&gt; &#34;sendcmpct&#34; message. In this mode, peers send new block announcements&#xA;&gt; with the short transaction IDs already, possibly even before fully&#xA;&gt; validating the block. In some cases no further round-trip is needed, and&#xA;&gt; the receiver can reconstruct the block and process it as usual&#xA;&gt; immediately. When some transactions were not available from local&#xA;&gt; sources (ie mempool), a getblocktxn/blocktxn roundtrip is neccessary,&#xA;&gt; bringing the best-case latency to the same 1.5*RTT minimum time that&#xA;&gt; nodes take today, though with significantly less bandwidth usage.&#xA;&gt;&#xA;&gt; The &#34;low-bandwidth&#34; mode is enabled by setting the first boolean to 0 in&#xA;&gt; a &#34;sendcmpct&#34; message. In this mode, peers send new block announcements&#xA;&gt; with the usual inv/headers announcements (as per BIP130, and after fully&#xA;&gt; validating the block). The receiving peer may then request the block&#xA;&gt; using a MSG_CMPCT_BLOCK getdata reqeuest, which will receive a response&#xA;&gt; of the header and short transaction IDs. In some cases no further&#xA;&gt; round-trip is needed, and the receiver can reconstruct the block and&#xA;&gt; process it as usual, taking the same 1.5*RTT minimum time that nodes&#xA;&gt; take today, though with significantly less bandwidth usage. When some&#xA;&gt; transactions were not available from local sources (ie mempool), a&#xA;&gt; getblocktxn/blocktxn roundtrip is neccessary, bringing the best-case&#xA;&gt; latency to 2.5*RTT, again with significantly less bandwidth usage than&#xA;&gt; today. Because TCP often exhibits worse transfer latency for larger data&#xA;&gt; sizes (as a multiple of RTT), total latency is expected to be reduced&#xA;&gt; even when full the 2.5*RTT transfer mechanism is used.&#xA;&gt;&#xA;&gt; ===New data structures===&#xA;&gt; Several new data structures are added to the P2P network to relay&#xA;&gt; compact blocks: PrefilledTransaction, HeaderAndShortIDs,&#xA;&gt; BlockTransactionsRequest, and BlockTransactions. Additionally, we&#xA;&gt; introduce a new variable-length integer encoding for use in these data&#xA;&gt; structures.&#xA;&gt;&#xA;&gt; For the purposes of this section, CompactSize refers to the&#xA;&gt; variable-length integer encoding used across the existing P2P protocol&#xA;&gt; to encode array lengths, among other things, in 1, 3, 5 or 9 bytes.&#xA;&gt;&#xA;&gt; ====New VarInt====&#xA;&gt; TODO: I just copied this out of the src...Something that is&#xA;&gt; wiki-formatted and more descriptive should be used here isntead.&#xA;&gt;&#xA;&gt; Variable-length integers: bytes are a MSB base-128 encoding of the number.&#xA;&gt; The high bit in each byte signifies whether another digit follows. To make&#xA;&gt; sure the encoding is one-to-one, one is subtracted from all but the last&#xA;&gt; digit.&#xA;&gt; Thus, the byte sequence a[] with length len, where all but the last byte&#xA;&gt; has bit 128 set, encodes the number:&#xA;&gt;&#xA;&gt; (a[len-1] &amp; 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] &amp; 0x7F)+1))&#xA;&gt;&#xA;&gt; Properties:&#xA;&gt; * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)&#xA;&gt; * Every integer has exactly one encoding&#xA;&gt; * Encoding does not depend on size of original integer type&#xA;&gt; * No redundancy: every (infinite) byte sequence corresponds to a list&#xA;&gt;   of encoded integers.&#xA;&gt;&#xA;&gt; 0:         [0x00]  256:        [0x81 0x00]&#xA;&gt; 1:         [0x01]  16383:      [0xFE 0x7F]&#xA;&gt; 127:       [0x7F]  16384:      [0xFF 0x00]&#xA;&gt; 128:  [0x80 0x00]  16511: [0x80 0xFF 0x7F]&#xA;&gt; 255:  [0x80 0x7F]  65535: [0x82 0xFD 0x7F]&#xA;&gt; 2^32:           [0x8E 0xFE 0xFE 0xFF 0x00]&#xA;&gt;&#xA;&gt; Several uses of New VarInts below are &#34;differentially encoded&#34;. For&#xA;&gt; these, instead of using raw indexes, the number encoded is the&#xA;&gt; difference between the current index and the previous index, minus one.&#xA;&gt; For example, a first index of 0 implies a real index of 0, a second&#xA;&gt; index of 0 thereafter refers to a real index of 1, etc.&#xA;&gt;&#xA;&gt; ====PrefilledTransaction====&#xA;&gt; A PrefilledTransaction structure is used in HeaderAndShortIDs to provide&#xA;&gt; a list of a few transactions explicitly.&#xA;&gt;&#xA;&gt; {|&#xA;&gt; |Field Name||Type||Size||Encoding||Purpose&#xA;&gt; |-&#xA;&gt; |index||New VarInt||1-3 bytes||[[#New_VarInt|New VarInt]],&#xA;&gt; differentially encoded since the last PrefilledTransaction in a&#xA;&gt; list||The index into the block at which this transaction is&#xA;&gt; |-&#xA;&gt; |tx||Transaction||variable||As encoded in &#34;tx&#34; messages||The transaction&#xA;&gt; which is in the block at index index.&#xA;&gt; |}&#xA;&gt;&#xA;&gt; ====HeaderAndShortIDs====&#xA;&gt; A HeaderAndShortIDs structure is used to relay a block header, the short&#xA;&gt; transactions IDs used for matching already-available transactions, and a&#xA;&gt; select few transactions which we expect a peer may be missing.&#xA;&gt;&#xA;&gt; {|&#xA;&gt; |Field Name||Type||Size||Encoding||Purpose&#xA;&gt; |-&#xA;&gt; |header||Block header||80 bytes||First 80 bytes of the block as defined&#xA;&gt; by the encoding used by &#34;block&#34; messages||The header of the block being&#xA;&gt; provided&#xA;&gt; |-&#xA;&gt; |nonce||uint64_t||8 bytes||Little Endian||A nonce for use in short&#xA;&gt; transaction ID calculations&#xA;&gt; |-&#xA;&gt; |shortids_length||CompactSize||1, 3, 5, or 9 bytes||As used elsewhere to&#xA;&gt; encode array lengths||The number of short transaction IDs in shortids&#xA;&gt; |-&#xA;&gt; |shortids||List of uint64_ts||8*shortids_length bytes||Little&#xA;&gt; Endian||The short transaction IDs calculated from the transactions which&#xA;&gt; were not provided explicitly in prefilledtxn&#xA;&gt; |-&#xA;&gt; |prefilledtxn_length||CompactSize||1, 3, 5, or 9 bytes||As used&#xA;&gt; elsewhere to encode array lengths||The number of prefilled transactions&#xA;&gt; in prefilledtxn&#xA;&gt; |-&#xA;&gt; |prefilledtxn||List of PrefilledTransactions||variable&#xA;&gt; size*prefilledtxn_length||As defined by PrefilledTransaction definition,&#xA;&gt; above||Used to provide the coinbase transaction and a select few which&#xA;&gt; we expect a peer may be missing&#xA;&gt; |}&#xA;&gt;&#xA;&gt; ====BlockTransactionsRequest====&#xA;&gt; A BlockTransactionsRequest structure is used to list transaction indexes&#xA;&gt; in a block being requested.&#xA;&gt;&#xA;&gt; {|&#xA;&gt; |Field Name||Type||Size||Encoding||Purpose&#xA;&gt; |-&#xA;&gt; |blockhash||Binary blob||32 bytes||The output from a double-SHA256 of&#xA;&gt; the block header, as used elsewhere||The blockhash of the block which&#xA;&gt; the transactions being requested are in&#xA;&gt; |-&#xA;&gt; |indexes_length||New VarInt||1-3 bytes||As defined in [[#New_VarInt|New&#xA;&gt; VarInt]]||The number of transactions being requested&#xA;&gt; |-&#xA;&gt; |indexes||List of New VarInts||1-3 bytes*indexes_length||As defined in&#xA;&gt; [[#New_VarInt|New VarInt]], differentially encoded||The indexes of the&#xA;&gt; transactions being requested in the block&#xA;&gt; |}&#xA;&gt;&#xA;&gt; ====BlockTransactions====&#xA;&gt; A BlockTransactions structure is used to provide some of the&#xA;&gt; transactions in a block, as requested.&#xA;&gt;&#xA;&gt; {|&#xA;&gt; |Field Name||Type||Size||Encoding||Purpose&#xA;&gt; |-&#xA;&gt; |blockhash||Binary blob||32 bytes||The output from a double-SHA256 of&#xA;&gt; the block header, as used elsewhere||The blockhash of the block which&#xA;&gt; the transactions being provided are in&#xA;&gt; |-&#xA;&gt; |transactions_length||New VarInt||1-3 bytes||As defined in&#xA;&gt; [[#New_VarInt|New VarInt]]||The number of transactions provided&#xA;&gt; |-&#xA;&gt; |transactions||List of Transactions||variable||As encoded in &#34;tx&#34;&#xA;&gt; messages||The transactions provided&#xA;&gt; |}&#xA;&gt;&#xA;&gt; ====Short transaction IDs====&#xA;&gt; Short transaction IDs are used to represent a transaction without&#xA;&gt; sending a full 256-bit hash. They are calculated by:&#xA;&gt; # single-SHA256 hashing the block header with the nonce appended (in&#xA;&gt; little-endian)&#xA;&gt; # XORing each 8-byte chunk of the double-SHA256 transaction hash with&#xA;&gt; each corresponding 8-byte chunk of the hash from the previous step&#xA;&gt; # Adding each of the XORed 8-byte chunks together (in little-endian)&#xA;&gt; iteratively to find the short transaction ID&#xA;&gt;&#xA;&gt; ===New messages===&#xA;&gt; A new inv type (MSG_CMPCT_BLOCK == 4) and several new protocol messages&#xA;&gt; are added: sendcmpct, cmpctblock, getblocktxn, and blocktxn.&#xA;&gt;&#xA;&gt; ====sendcmpct====&#xA;&gt; # The sendcmpct message is defined as a message containing a 1-byte&#xA;&gt; integer followed by a 8-byte integer where pchCommand == &#34;sendcmpct&#34;.&#xA;&gt; # The first integer SHALL be interpreted as a boolean (and MUST have a&#xA;&gt; value of either 1 or 0)&#xA;&gt; # The second integer SHALL be interpreted as a little-endian version&#xA;&gt; number. Nodes sending a sendcmpct message MUST currently set this value&#xA;&gt; to 1.&#xA;&gt; # Upon receipt of a &#34;sendcmpct&#34; message with the first and second&#xA;&gt; integers set to 1, the node SHOULD announce new blocks by sending a&#xA;&gt; cmpctblock message.&#xA;&gt; # Upon receipt of a &#34;sendcmpct&#34; message with the first integer set to 0,&#xA;&gt; the node SHOULD NOT announce new blocks by sending a cmpctblock message,&#xA;&gt; but SHOULD announce new blocks by sending invs or headers, as defined by&#xA;&gt; BIP130.&#xA;&gt; # Upon receipt of a &#34;sendcmpct&#34; message with the second integer set to&#xA;&gt; something other than 1, nodes SHOULD treat the peer as if they had not&#xA;&gt; received the message (as it indicates the peer will provide an&#xA;&gt; unexpected encoding in cmpctblock, and/or other, messages)&#xA;&gt; # Nodes SHOULD check for a protocol version of &gt;= 70014 before sending&#xA;&gt; sendcmpct messages.&#xA;&gt; # Nodes MUST NOT send a request for a MSG_CMPCT_BLOCK object to a peer&#xA;&gt; before having received a sendcmpct message from that peer.&#xA;&gt;&#xA;&gt; ====MSG_CMPCT_BLOCK====&#xA;&gt; # getdata messages may now contain requests for MSG_CMPCT_BLOCK objects.&#xA;&gt; # Upon receipt of a getdata containing a request for a MSG_CMPCT_BLOCK&#xA;&gt; object with the hash of a block which was recently announced and after&#xA;&gt; having sent the requesting peer a sendcmpct message, nodes MUST respond&#xA;&gt; with a cmpctblock message containing appropriate data representing the&#xA;&gt; block being requested.&#xA;&gt; # MSG_CMPCT_BLOCK inv objects MUST NOT appear anywhere except for in&#xA;&gt; getdata messages.&#xA;&gt;&#xA;&gt; ====cmpctblock====&#xA;&gt; # The cmpctblock message is defined as as a message containing a&#xA;&gt; serialized HeaderAndShortIDs message and pchCommand == &#34;cmpctblock&#34;.&#xA;&gt; # Upon receipt of a cmpctblock message after sending a sendcmpct&#xA;&gt; message, nodes SHOULD calculate the short transaction ID for each&#xA;&gt; unconfirmed transaction they have available (ie in their mempool) and&#xA;&gt; compare each to each short transaction ID in the cmpctblock message.&#xA;&gt; # After finding already-available transactions, nodes which do not have&#xA;&gt; all transactions available to reconstruct the full block SHOULD request&#xA;&gt; the missing transactions using a getblocktxn message.&#xA;&gt; # A node MUST NOT send a cmpctblock message unless they are able to&#xA;&gt; respond to a getblocktxn message which requests every transaction in the&#xA;&gt; block.&#xA;&gt; # A node MUST NOT send a cmpctblock message without having validated&#xA;&gt; that the header properly commits to each transaction in the block, and&#xA;&gt; properly builds on top of the existing chain with a valid proof-of-work.&#xA;&gt; A node MAY send a cmpctblock before validating that each transaction in&#xA;&gt; the block validly spends existing UTXO set entries.&#xA;&gt;&#xA;&gt; ====getblocktxn====&#xA;&gt; # The getblocktxn message is defined as as a message containing a&#xA;&gt; serialized BlockTransactionsRequest message and pchCommand ==&#xA;&gt; &#34;getblocktxn&#34;.&#xA;&gt; # Upon receipt of a properly-formatted getblocktxnmessage, nodes which&#xA;&gt; recently provided the sender of such a message a cmpctblock for the&#xA;&gt; block hash identified in this message MUST respond with an appropriate&#xA;&gt; blocktxn message. Such a blocktxn message MUST contain exactly and only&#xA;&gt; each transaction which is present in the appropriate block at the index&#xA;&gt; specified in the getblocktxn indexes list, in the order requested.&#xA;&gt;&#xA;&gt; ====blocktxn====&#xA;&gt; # The blocktxn message is defined as as a message containing a&#xA;&gt; serialized BlockTransactions message and pchCommand == &#34;blocktxn&#34;.&#xA;&gt; # Upon receipt of a properly-formatted requested blocktxn message, nodes&#xA;&gt; SHOULD attempt to reconstruct the full block by:&#xA;&gt; ## Taking the prefilledtxn transactions from the original cmpctblock and&#xA;&gt; placing them in the marked positions.&#xA;&gt; ## For each short transaction ID from the original cmpctblock, in order,&#xA;&gt; find the corresponding transaction either from the blocktxn message or&#xA;&gt; from other sources and place it in the first available position in the&#xA;&gt; block.&#xA;&gt; # Once the block has been reconstructed, it shall be processed as&#xA;&gt; normal, keeping in mind that short transaction IDs are expected to&#xA;&gt; occasionally collide, and that nodes MUST NOT be penalized for such&#xA;&gt; collisions, wherever they appear.&#xA;&gt;&#xA;&gt; ===Implementation Notes===&#xA;&gt; # For nodes which have sufficient inbound bandwidth, sending a sendcmpct&#xA;&gt; message with the first integer set to 1 to up to three peers is&#xA;&gt; RECOMMENDED. If possible, it is RECOMMENDED that those peers be selected&#xA;&gt; based on their past performance in providing blocks quickly. This will&#xA;&gt; allow them to receive some blocks in only 0.5*RTT between them and the&#xA;&gt; sending peer. It will also reduce their block transfer latency in other&#xA;&gt; cases due to the smaller amount of data transmitted. Nodes MUST NOT send&#xA;&gt; such sendcmpct messages to all peers, as it encourages wasting outbound&#xA;&gt; bandwidth across the network.&#xA;&gt;&#xA;&gt; # All nodes SHOULD send a sendcmpct message to all appropriate peers.&#xA;&gt; This will reduce their outbound bandwidth usage by allowing their peers&#xA;&gt; to request compact blocks instead of full blocks.&#xA;&gt;&#xA;&gt; # Nodes with limited inbound bandwidth SHOULD request blocks using&#xA;&gt; MSG_CMPCT_BLOCK/getblocktxn requests, when possible. While this&#xA;&gt; increases worst-case message round-trips, it is expected to reduce&#xA;&gt; overall transfer latency as TCP is more likely to exhibit poor&#xA;&gt; throughput on low-bandwidth nodes.&#xA;&gt;&#xA;&gt; # Nodes sending cmpctblock messages SHOULD make an attempt to not place&#xA;&gt; too many transactions into prefilledtxn (ie should limit prefilledtxn to&#xA;&gt; only around 10KB of transactions). When in doubt, nodes SHOULD only&#xA;&gt; include the coinbase transaction in prefilledtxn.&#xA;&gt;&#xA;&gt; # Nodes MAY pick one nonce per block they wish to send, and only build a&#xA;&gt; cmpctblock message once for all peers which they wish to send a given&#xA;&gt; block to. Nodes SHOULD NOT use the same nonce across multiple different&#xA;&gt; blocks.&#xA;&gt;&#xA;&gt; # Nodes MAY impose additional requirements on when they announce new&#xA;&gt; blocks by sending cmpctblock messages. For example, nodes with limited&#xA;&gt; outbound bandwidth MAY choose to announce new blocks using inv/header&#xA;&gt; messages (as per BIP130) to conserve outbound bandwidth.&#xA;&gt;&#xA;&gt; # Note that the MSG_CMPCT_BLOCK section does not require that nodes&#xA;&gt; respond to MSG_CMPCT_BLOCK getdata requests for blocks which they did&#xA;&gt; not recently announce. This allows nodes to calculate cmpctblock&#xA;&gt; messages at announce-time instead of at request-time. Thus, nodes MUST&#xA;&gt; NOT request blocks using MSG_CMPCT_BLOCK getdatas unless it is in&#xA;&gt; response to an inv/headers block announcement (as per BIP130), and MUST&#xA;&gt; NOT request blocks using MSG_CMPCT_BLOCK getdatas in response to headers&#xA;&gt; messages which were, themselves, responses to getheaders requests.&#xA;&gt;&#xA;&gt; # While the current version sends transactions with the same encodings&#xA;&gt; as is used in tx messages and elsewhere in the protocol, the version&#xA;&gt; field in sendcmpct is intended to allow this to change in the future.&#xA;&gt; For this reason, it is recommended that the code used to decode&#xA;&gt; PrefilledTransaction and BlockTransactions messages be prepared to take&#xA;&gt; a different transaction encoding, if and when the version field in&#xA;&gt; sendcmpct changes in a future BIP.&#xA;&gt;&#xA;&gt; ==Justification==&#xA;&gt;&#xA;&gt; ====Protocol design====&#xA;&gt; There have been many proposals to save wire bytes when relaying blocks.&#xA;&gt; Many of them have a two-fold goal of reducing block relay time and thus&#xA;&gt; rely on the use of significant processing power in order to avoid&#xA;&gt; introducing additional worst-case RTTs. Because this work is not focused&#xA;&gt; primarily on reducing block relay time, its design is much simpler (ie&#xA;&gt; does not rely on set reconciliation protocols). Still, in testing at the&#xA;&gt; time of writing, nodes are able to relay blocks without the extra&#xA;&gt; getblocktxn/blocktxn RTT around 90% of the time. With a smart&#xA;&gt; compact-block-announcement policy, it is thus expected that this work&#xA;&gt; might allow blocks to be relayed between nodes in 0.5*RTT instead of&#xA;&gt; 1.5*RTT at least 75% of the time.&#xA;&gt;&#xA;&gt; ====Use of New VarInts====&#xA;&gt; Bitcoin has long had a variable-length integer implementation (referred&#xA;&gt; to as CompactSize in this document), making a second a strange protocol&#xA;&gt; quirk. However, in this protocol most of our variable-length integers&#xA;&gt; are between 0 and 2000. For both encodings, small numbers (&lt;100) are&#xA;&gt; encoded as 1-byte. For numbers over 250, the CompactSize encoding begins&#xA;&gt; to use 3 bytes instead of 1, whereas the New VarInt encoding uses 2.&#xA;&gt; Because the primary motivation for this work is to save bytes during&#xA;&gt; block relay, the extra byte of saving per transaction-difference is&#xA;&gt; considered worth the extra design complexity.&#xA;&gt;&#xA;&gt; ====Short transaction ID calculation====&#xA;&gt; The short transaction ID calculation is designed to take absolutely&#xA;&gt; minimal processing time during block compaction to avoid introducing&#xA;&gt; serious DoS vulnerabilities such as those introduced by the&#xA;&gt; bloom-filtering in BIP 37. As such, it is possible for a node to&#xA;&gt; construct one compact-block representation of a block for relay to&#xA;&gt; multiple peers. Additionally, only one cryptographic hash (2 SHA rounds)&#xA;&gt; is used when calculating the short transaction IDs for an entire block.&#xA;&gt;&#xA;&gt; The XOR-and-add method is used for calculating short transaction IDs&#xA;&gt; primarily because it is fast and is reasonably able to limit the ability&#xA;&gt; of an attacker who does not know the block hash or nonce to cause&#xA;&gt; collisions in short transaction IDs. If an attacker were able to cause&#xA;&gt; such collisions, filling mempools (and, thus, blocks) with them would&#xA;&gt; cause poor network propagation of new (or non-attacker, in the case of a&#xA;&gt; miner) blocks.&#xA;&gt;&#xA;&gt; The 8-byte nonce in short transaction ID calculation is used to&#xA;&gt; introduce additional entropy on a per-node level. While the use of 8&#xA;&gt; bytes is sufficient for an attacker to maliciously cause short&#xA;&gt; transaction ID collisions in their own block relay, this would have less&#xA;&gt; of an effect than if such an attacker were relaying headers/invs and not&#xA;&gt; responding to requests for the full block.&#xA;&gt;&#xA;&gt; ==Backward compatibility==&#xA;&gt;&#xA;&gt; Older clients remain fully compatible and interoperable after this change.&#xA;&gt;&#xA;&gt; ==Implementation==&#xA;&gt;&#xA;&gt; https://github.com/TheBlueMatt/bitcoin/tree/udp&#xA;&gt;&#xA;&gt; ==Acknowledgements==&#xA;&gt;&#xA;&gt; Thanks to Gregory Maxwell for the initial suggestion as well as a lot of&#xA;&gt; back-and-forth design and significant testing.&#xA;&gt;&#xA;&gt; ==Copyright==&#xA;&gt;&#xA;&gt; This document is placed in the public domain.&#xA;&gt;&#xA;&gt; _______________________________________________&#xA;&gt; bitcoin-dev mailing list&#xA;&gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&#xA;&#xA;&#xA;&#xA;-- &#xA;Johnathan Corgan&#xA;Corgan Labs - SDR Training and Development Services&#xA;http://corganlabs.com&#xA;-------------- next part --------------&#xA;An HTML attachment was scrubbed...&#xA;URL: &lt;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20160507/028cac26/attachment-0001.html&gt;</html></oembed>