1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
Return-Path: <bram@bittorrent.com>
Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
[172.17.192.35])
by mail.linuxfoundation.org (Postfix) with ESMTPS id 3179B3EE
for <bitcoin-dev@lists.linuxfoundation.org>;
Thu, 16 Jun 2016 01:16:48 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.7.6
Received: from mail-io0-f172.google.com (mail-io0-f172.google.com
[209.85.223.172])
by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1BACE1A9
for <bitcoin-dev@lists.linuxfoundation.org>;
Thu, 16 Jun 2016 01:16:47 +0000 (UTC)
Received: by mail-io0-f172.google.com with SMTP id t74so29257755ioi.0
for <bitcoin-dev@lists.linuxfoundation.org>;
Wed, 15 Jun 2016 18:16:47 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=bittorrent-com.20150623.gappssmtp.com; s=20150623;
h=mime-version:in-reply-to:references:from:date:message-id:subject:to
:cc; bh=NUdX1KXK2I97NEdBImHYkxrqiMe3Hwt38qF52PCe2Gk=;
b=nf42RPTmOglNDnrNrJGkT+nALA8CFN9+rmaoXsHBWWDDMYoAwqN0ZKDOVx7lvtcFXt
19AVwuwFNzFfT8isR5UfP8IVPqHfQprj+C5jKkSngTW2tsiduesznP6A4kuwLa0wyZtq
0GS92yPDICU0ygw+03V1YSgj0HV0fdMhP/FzoV62+y3Klgd/3ZvNtKQqQ/tEU40plwFt
VfExL7ing/ZNnbX4kTgPXfTEhz0gOBfxyvMPjeFq1W2jr7sjICHdTlRvpezF7kJWJt4r
erpCn8yTauJmsCxtCJS4mtNtyBRn+L3IQwMs6RwqgmvL1DB1c644CR3mWwcWUx3ZZ0NZ
D8Hw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20130820;
h=x-gm-message-state:mime-version:in-reply-to:references:from:date
:message-id:subject:to:cc;
bh=NUdX1KXK2I97NEdBImHYkxrqiMe3Hwt38qF52PCe2Gk=;
b=CsPGz3NowC6qf5AvM2Cb5uFokPN7ckdtwQBLjZRhoSgGN6Rf8hGGa4pEIcBvfoD5Y+
Mm1Au7+vtl17sOpQMMg5jnbzAU/FYlwOYGu18ZvGgebrl1++SU+li81qpI37BJuTeZ/r
dFLHQwQLD+XTKxChYnSXb4gl3gMe2jo8Lh4azPHkrhpUi/pMIBqbHJ0nLz5iD9G3PiL/
gI0+xmVbPAsruri99yyFMupkL+fN5Z5eUTDR3RMz09f1UYM/7XleFXRtmPD6lyGsohcF
kecshBWqw+3zTvgHHlRedB5hSgAAEmrBXPm9pmtDaNslIhPi64/UUpX6gjLJak74RQ76
i20g==
X-Gm-Message-State: ALyK8tKahI8X6p4gpcJuTzJttBzD7EcP1CK6sSMcepuqoprU/RFnmaYgNCmHbfYS0hwidZBpW9+NWwkNavTNyrHe
X-Received: by 10.107.205.8 with SMTP id d8mr3648697iog.113.1466039806307;
Wed, 15 Jun 2016 18:16:46 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.36.134.68 with HTTP; Wed, 15 Jun 2016 18:16:26 -0700 (PDT)
In-Reply-To: <20160616001040.GA5026@fedora-21-dvm>
References: <CA+KqGkosGrWQ2Lpg3Ptc+UyidK7H4_HLQ_QWx2DOAFRmLkv4zQ@mail.gmail.com>
<20160616001040.GA5026@fedora-21-dvm>
From: Bram Cohen <bram@bittorrent.com>
Date: Wed, 15 Jun 2016 18:16:26 -0700
Message-ID: <CA+KqGkqAHcU2PzEX6OmorXRBQ22eF_QBYYqUDS1v_ZvevhLCuQ@mail.gmail.com>
To: Peter Todd <pete@petertodd.org>
Content-Type: multipart/alternative; boundary=94eb2c1880dce1cb0805355afde8
X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,
DKIM_VALID,HTML_MESSAGE,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
smtp1.linux-foundation.org
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Subject: Re: [bitcoin-dev] Merkle trees and mountain ranges
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Thu, 16 Jun 2016 01:16:48 -0000
--94eb2c1880dce1cb0805355afde8
Content-Type: text/plain; charset=UTF-8
On Wed, Jun 15, 2016 at 5:10 PM, Peter Todd <pete@petertodd.org> wrote:
> On Tue, Jun 14, 2016 at 05:14:23PM -0700, Bram Cohen via bitcoin-dev wrote:
> >
> > Peter proposes that there should be both UTXO and STXO commitments, and
>
> No, that's incorrect - I'm only proposing TXO commitments, not UTXO nor
> STXO
> commitments.
>
What do you mean by TXO commitments? If you mean that it only records
insertions rather than deletions, then that can do many of the same proofs
but has no way of proving that something is currently in the UTXO set,
which is functionality I'd like to provide.
When I say 'merkle tree' what I mean is a patricia trie. What I assume is
meant by a merkle mountain range is a series of patricia tries of
decreasing size each of which is an addition to the previous one, and
they're periodically consolidated into larger tries so the old ones can go
away. This data structure has the nice property that it's both in sorted
order and has less than one cache miss per operation because the
consolidation operations can be batched and done linearly. There are a
number of different things you could be describing if I misunderstood.
> I'm not proposing STXO commitments precisely because the set of _spent_
> transactions grows without bound.
I'm worried that once there's real transaction fees everyone might stop
consolidating dust and the set of unspent transactions might grow without
bound as well, but that's a topic for another day.
> > Now I'm going to go out on a limb. My thesis is that usage of a mountain
> > range is unnecessary, and that a merkle tree in the raw can be made
> > serviceable by sprinkling magic pixie dust on the performance problem.
>
> It'd help if you specified exactly what type of merkle tree you're talking
> about here; remember that the certificate transparency RFC appears to have
> reinvented merkle mountain ranges, and they call them "merkle trees".
> Bitcoin
> meanwhile uses a so-called "merkle tree" that's broken, and Zcash uses a
> partially filled fixed-sized perfect tree.
>
What I'm making is a patricia trie. Its byte level definition is very
similar to the one in your MMR codebase.
Each level of the tree has a single metadata byte and followed by two
hashes. The hashes are truncated by one byte and the hash function is a
non-padding variant of sha256 (right now it's just using regular sha256,
but that's a nice optimization which allows everything to fit in a single
block).
The possible metadata values are: TERM0, TERM1, TERMBOTH, ONLY0, ONLY1,
MIDDLE. They mean:
TERM0, TERM1: There is a single thing in the tree on the specified side.
The thing hashed on that side is that thing verbatim. The other side has
more than one thing and the hash of it is the root of everything below.
TERMBOTH: There are exactly two things below and they're included inline.
Note that two things is a special case, if there are more you sometimes
have ONLY0 or ONLY1.
ONLY0, ONLY1: There are more than two things below and they're all on the
same side. This makes proofs of inclusion and exclusion simpler, and makes
some implementation details easier, for example there's always something at
every level with perfect memory positioning. It doesn't cause much extra
memory usage because of the TERMBOTH exception for exactly two things.
MIDDLE: There two or more things on both sides.
There's also a SINGLETON special case for a tree which contains only one
thing, and an EMPTY special value for tree which doesn't contain anything.
The main differences to your patricia trie are the non-padding sha256 and
that each level doesn't hash in a record of its depth and the usage of
ONLY0 and ONLY1.
>
> > There are two causes of performance problems for merkle trees: hashing
> > operations and memory cache misses. For hashing functions, the difference
> > between a mountain range and a straight merkle tree is roughly that in a
> > mountain range there's one operation for each new update times the number
> > of times that thing will get merged into larger hills. If there are fewer
> > levels of hills the number of operations is less but the expense of proof
> > of inclusion will be larger. For raw merkle trees the number of
> operations
> > per thing added is the log base 2 of the number of levels in the tree,
> > minus the log base 2 of the number of things added at once since you can
> do
> > lazy evaluation. For practical Bitcoin there are (very roughly) a million
> > things stored, or 20 levels, and there are (even more roughly) about a
> > thousand things stored per block, so each thing forces about 20 - 10 = 10
> > operations. If you follow the fairly reasonable guideline of mountain
> range
> > hills go up by factors of four, you instead have 20/2 = 10 operations per
> > thing added amortized. Depending on details this comparison can go either
> > way but it's roughly a wash and the complexity of a mountain range is
> > clearly not worth it at least from the point of view of CPU costs.
>
> I'm having a hard time understanding this paragraph; could you explain
> what you
> think is happening when things are "merged into larger hills"?
>
I'm talking about the recalculation of mountain tips, assuming we're on the
same page about what 'MMR' means.
> As UTXO/STXO/TXO sets are all enormously larger than L1/L2 cache, it's
> impossible to get CPU cache misses below one for update operations. The
> closest
> thing to an exception is MMR's, which due to their insertion-ordering could
> have good cache locality for appends, in the sense that the mountain tips
> required to recalculate the MMR tip digest will already be in cache from
> the
> previous append. But that's not sufficient, as you also need to modify old
> TXO's further back in the tree to mark them as spent - that data is going
> to be
> far larger than L1/L2 cache.
>
This makes me think we're talking about subtly different things for MMRs.
The ones I described above have sub-1 cache miss per update due to the
amortized merging together of old mountains.
Technically even a patricia trie utxo commitment can have sub-1 cache
misses per update if some of the updates in a single block are close to
each other in memory. I think I can get practical Bitcoin updates down to a
little bit less than one l2 cache miss per update, but not a lot less.
--94eb2c1880dce1cb0805355afde8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Jun 15, 2016 at 5:10 PM, Peter Todd <span dir=3D"ltr"><<a href=3D"ma=
ilto:pete@petertodd.org" target=3D"_blank">pete@petertodd.org</a>></span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Tue, Jun 14,=
2016 at 05:14:23PM -0700, Bram Cohen via bitcoin-dev wrote:<br>><br>
> Peter proposes that there should be both UTXO and STXO commitments, an=
d<br>
<br>
</span>No, that's incorrect - I'm only proposing TXO commitments, n=
ot UTXO nor STXO<br>
commitments.<br></blockquote><div><br></div><div>What do you mean by TXO co=
mmitments? If you mean that it only records insertions rather than deletion=
s, then that can do many of the same proofs but has no way of proving that =
something is currently in the UTXO set, which is functionality I'd like=
to provide.</div><div><br></div><div>When I say 'merkle tree' what=
I mean is a patricia trie. What I assume is meant by a merkle mountain ran=
ge is a series of patricia tries of decreasing size each of which is an add=
ition to the previous one, and they're periodically consolidated into l=
arger tries so the old ones can go away. This data structure has the nice p=
roperty that it's both in sorted order and has less than one cache miss=
per operation because the consolidation operations can be batched and done=
linearly. There are a number of different things you could be describing i=
f I misunderstood.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I&#=
39;m not proposing STXO commitments precisely because the set of _spent_<br=
>
transactions grows without bound. </blockquote><div><br></div><div>I'm =
worried that once there's real transaction fees everyone might stop con=
solidating dust and the set of unspent transactions might grow without boun=
d as well, but that's a topic for another day.</div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><span class=3D"">> Now I'm going to go =
out on a limb. My thesis is that usage of a mountain<br>
> range is unnecessary, and that a merkle tree in the raw can be made<br=
>
> serviceable by sprinkling magic pixie dust on the performance problem.=
<br>
<br>
</span>It'd help if you specified exactly what type of merkle tree you&=
#39;re talking<br>
about here; remember that the certificate transparency RFC appears to have<=
br>
reinvented merkle mountain ranges, and they call them "merkle trees&qu=
ot;.=C2=A0 Bitcoin<br>
meanwhile uses a so-called "merkle tree" that's broken, and Z=
cash uses a<br>
partially filled fixed-sized perfect tree.<br></blockquote><div><br></div><=
div>What I'm making is a patricia trie. Its byte level definition is ve=
ry similar to the one in your MMR codebase.</div><div><br></div><div>Each l=
evel of the tree has a single metadata byte and followed by two hashes. The=
hashes are truncated by one byte and the hash function is a non-padding va=
riant of sha256 (right now it's just using regular sha256, but that'=
;s a nice optimization which allows everything to fit in a single block).</=
div><div><br></div><div>The possible metadata values are: TERM0, TERM1, TER=
MBOTH, ONLY0, ONLY1, MIDDLE. They mean:</div><div><br></div><div>TERM0, TER=
M1: There is a single thing in the tree on the specified side. The thing ha=
shed on that side is that thing verbatim. The other side has more than one =
thing and the hash of it is the root of everything below.</div><div><br></d=
iv><div>TERMBOTH: There are exactly two things below and they're includ=
ed inline. Note that two things is a special case, if there are more you so=
metimes have ONLY0 or ONLY1.</div><div><br></div><div>ONLY0, ONLY1: There a=
re more than two things below and they're all on the same side. This ma=
kes proofs of inclusion and exclusion simpler, and makes some implementatio=
n details easier, for example there's always something at every level w=
ith perfect memory positioning. It doesn't cause much extra memory usag=
e because of the TERMBOTH exception for exactly two things.</div><div><br><=
/div><div>MIDDLE: There two or more things on both sides.</div><div><br></d=
iv><div>There's also a SINGLETON special case for a tree which contains=
only one thing, and an EMPTY special value for tree which doesn't cont=
ain anything.</div><div><br></div><div>The main differences to your patrici=
a trie are the non-padding sha256 and that each level doesn't hash in a=
record of its depth and the usage of ONLY0 and ONLY1.</div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">
<span class=3D""><br>
> There are two causes of performance problems for merkle trees: hashing=
<br>
> operations and memory cache misses. For hashing functions, the differe=
nce<br>
> between a mountain range and a straight merkle tree is roughly that in=
a<br>
> mountain range there's one operation for each new update times the=
number<br>
> of times that thing will get merged into larger hills. If there are fe=
wer<br>
> levels of hills the number of operations is less but the expense of pr=
oof<br>
> of inclusion will be larger. For raw merkle trees the number of operat=
ions<br>
> per thing added is the log base 2 of the number of levels in the tree,=
<br>
> minus the log base 2 of the number of things added at once since you c=
an do<br>
> lazy evaluation. For practical Bitcoin there are (very roughly) a mill=
ion<br>
> things stored, or 20 levels, and there are (even more roughly) about a=
<br>
> thousand things stored per block, so each thing forces about 20 - 10 =
=3D 10<br>
> operations. If you follow the fairly reasonable guideline of mountain =
range<br>
> hills go up by factors of four, you instead have 20/2 =3D 10 operation=
s per<br>
> thing added amortized. Depending on details this comparison can go eit=
her<br>
> way but it's roughly a wash and the complexity of a mountain range=
is<br>
> clearly not worth it at least from the point of view of CPU costs.<br>
<br>
</span>I'm having a hard time understanding this paragraph; could you e=
xplain what you<br>
think is happening when things are "merged into larger hills"?<br=
></blockquote><div><br></div><div>I'm talking about the recalculation o=
f mountain tips, assuming we're on the same page about what 'MMR=
9; means.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">As UTXO/=
STXO/TXO sets are all enormously larger than L1/L2 cache, it's<br>
impossible to get CPU cache misses below one for update operations. The clo=
sest<br>
thing to an exception is MMR's, which due to their insertion-ordering c=
ould<br>
have good cache locality for appends, in the sense that the mountain tips<b=
r>
required to recalculate the MMR tip digest will already be in cache from th=
e<br>
previous append. But that's not sufficient, as you also need to modify =
old<br>
TXO's further back in the tree to mark them as spent - that data is goi=
ng to be<br>
far larger than L1/L2 cache.<br></blockquote><div><br></div><div>This makes=
me think we're talking about subtly different things for MMRs. The one=
s I described above have sub-1 cache miss per update due to the amortized m=
erging together of old mountains.</div><div><br></div><div>Technically even=
a patricia trie utxo commitment can have sub-1 cache misses per update if =
some of the updates in a single block are close to each other in memory. I =
think I can get practical Bitcoin updates down to a little bit less than on=
e l2 cache miss per update, but not a lot less.</div></div></div></div>
--94eb2c1880dce1cb0805355afde8--
|