summaryrefslogtreecommitdiff
path: root/2c/ff772316e9ea64cebbb422d3289a93aaa6af55
blob: 709a16351026df110cc17a2625b22cd42929d2d0 (plain)
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
Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192]
	helo=mx.sourceforge.net)
	by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76)
	(envelope-from <stephencalebmorse@gmail.com>) id 1Yugwd-0002v7-UC
	for bitcoin-development@lists.sourceforge.net;
	Tue, 19 May 2015 12:48:27 +0000
Received-SPF: pass (sog-mx-2.v43.ch3.sourceforge.com: domain of gmail.com
	designates 209.85.160.173 as permitted sender)
	client-ip=209.85.160.173;
	envelope-from=stephencalebmorse@gmail.com;
	helo=mail-yk0-f173.google.com; 
Received: from mail-yk0-f173.google.com ([209.85.160.173])
	by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128)
	(Exim 4.76) id 1Yugwc-0003BR-0q
	for bitcoin-development@lists.sourceforge.net;
	Tue, 19 May 2015 12:48:27 +0000
Received: by ykeo186 with SMTP id o186so4815306yke.0
	for <bitcoin-development@lists.sourceforge.net>;
	Tue, 19 May 2015 05:48:20 -0700 (PDT)
MIME-Version: 1.0
X-Received: by 10.170.89.5 with SMTP id g5mr30103078yka.30.1432039700553; Tue,
	19 May 2015 05:48:20 -0700 (PDT)
Received: by 10.13.245.70 with HTTP; Tue, 19 May 2015 05:48:20 -0700 (PDT)
In-Reply-To: <CALxbBHUvtoc25Eyh1KF=bmG8SbZd_UpO1QeUVLbicNqJQPHBLQ@mail.gmail.com>
References: <CALxbBHUnt7ToVK9reH6W6uT4HV=7NbxGHyNWWa-OEHg+Z1+qOg@mail.gmail.com>
	<5555C26F.7080706@sky-ip.org>
	<AC0B3BAC-0934-46A3-B29A-F74238616F72@gmail.com>
	<CALxbBHXC=jc+7Vj-3-VT7kj-+V6ORdeJPr_G9ymOcJyFZ3hy=A@mail.gmail.com>
	<CAE-z3OXC-uCYQmhGJd2ZVfLrEbAZVhEz0ejkbwmcRgK3kbjSrg@mail.gmail.com>
	<CALxbBHUvtoc25Eyh1KF=bmG8SbZd_UpO1QeUVLbicNqJQPHBLQ@mail.gmail.com>
Date: Tue, 19 May 2015 08:48:20 -0400
Message-ID: <CABHVRKSSCX8VS=T-bim_rw6VMJP-hnUi8AzLHyDM57KQi2zn+w@mail.gmail.com>
From: Stephen Morse <stephencalebmorse@gmail.com>
To: Christian Decker <decker.christian@gmail.com>
Content-Type: multipart/alternative; boundary=001a113a0528a7e73505166eb90c
X-Spam-Score: -0.6 (/)
X-Spam-Report: Spam Filtering performed by mx.sourceforge.net.
	See http://spamassassin.org/tag/ for more details.
	-1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for
	sender-domain
	0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
	(stephencalebmorse[at]gmail.com)
	-0.0 SPF_PASS               SPF: sender matches SPF record
	1.0 HTML_MESSAGE           BODY: HTML included in message
	-0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
	author's domain
	0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
	not necessarily valid
	-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
X-Headers-End: 1Yugwc-0003BR-0q
Cc: Bitcoin Development <bitcoin-development@lists.sourceforge.net>
Subject: Re: [Bitcoin-development] [BIP] Normalized Transaction IDs
X-BeenThere: bitcoin-development@lists.sourceforge.net
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: <bitcoin-development.lists.sourceforge.net>
List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=unsubscribe>
List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development>
List-Post: <mailto:bitcoin-development@lists.sourceforge.net>
List-Help: <mailto:bitcoin-development-request@lists.sourceforge.net?subject=help>
List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=subscribe>
X-List-Received-Date: Tue, 19 May 2015 12:48:28 -0000

--001a113a0528a7e73505166eb90c
Content-Type: text/plain; charset=UTF-8

>
> An option would be that the height is included in the scriptSig for all
>> transactions, but for non-coinbase transctions, the height used is zero.
>>
> No need to add an extra field to the transaction just to include the
> height. We can just add a rule that the height specified in the scriptSig
> in coinbase transactions (and only coinbase transactions) is copied into
> the locktime of the transaction before computing the normalized transaction
> ID and leave the locktime untouched for all normal transactions
>

No need to replace lock times (or any other part of the transaction) at
all. If you have to, just serialize the height right before serializing the
transaction (into the same buffer). And you could pre-serialize 0 instead
of the height for all non-coinbase transactions. I don't really see what
that gets you, though, because the 0 is not really doing anything.

But, I don't see any reason you have to mess with the serialization this
much at all. Just do:

uint256 normalized_txid(CTransaction tx)
{
  // Coinbase transactions are already normalized
  if (!tx.IsCoinbase())
  {
    foreach(CTxIn in : tx.vin)
    {
      if (!ReplacePrevoutHashWithNormalizedHash(in.prevout))
        throw NormalizationError("Could not lookup prevout");
      in.scriptSig.clear();
    }
  }

  // Serialize
  CHashWriter ss(SER_GETHASH, 0);
  ss << tx;
  return ss.GetHash();
}

An alternative could be (although I like the above option better):

uint256 normalized_txid(CTransaction tx, int nHeight)
{
  foreach(CTxIn in : tx.vin)
  {
    if (!in.prevout.IsNull() &&
!ReplacePrevoutHashWithNormalizedHash(in.prevout))
      throw NormalizationError("Could not lookup prevout");
    in.scriptSig.clear();
  }

  // Serialize
  CHashWriter ss(SER_GETHASH, 0);

if (tx.IsCoinbase())
ss << nHeight;
// or:
// ss << (tx.IsCoinbase() ? nHeight : 0);

  ss << tx;
  return ss.GetHash();
}

--001a113a0528a7e73505166eb90c
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><span class=3D""><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"g=
mail_quote"><div>An option would be that the height is included in the scri=
ptSig for all transactions, but for non-coinbase transctions, the height us=
ed is zero.<br></div></div></div></div></blockquote></span><div>No need to =
add an extra field to the transaction just to include the height. We can ju=
st add a rule that the height specified in the scriptSig in coinbase transa=
ctions (and only coinbase transactions) is copied into the locktime of the =
transaction before computing the normalized transaction ID and leave the lo=
cktime untouched for all normal transactions</div></div></div></blockquote>=
<div><br></div><div><div><span style=3D"background-color:rgba(255,255,255,0=
)">No need to replace=C2=A0lock times (or any other part of the transaction=
) at all. If you have to, just serialize the height right before serializin=
g the transaction (into the same buffer). And you could pre-serialize 0 ins=
tead of the height for all non-coinbase transactions. I don&#39;t really se=
e what that gets you, though, because the 0 is not really doing anything.</=
span></div><div><span style=3D"background-color:rgba(255,255,255,0)"><br></=
span></div><div><span style=3D"background-color:rgba(255,255,255,0)">But, I=
 don&#39;t see any reason you have to mess with the serialization this much=
 at all. Just do:</span></div><div><span style=3D"background-color:rgba(255=
,255,255,0)"><br></span></div><div><div><span style=3D"background-color:rgb=
a(255,255,255,0)"><font face=3D"monospace, monospace">uint256 normalized_tx=
id(CTransaction tx)</font></span></div><div><span style=3D"background-color=
:rgba(255,255,255,0)"><font face=3D"monospace, monospace">{</font></span></=
div><div><span style=3D"font-family:monospace,monospace">=C2=A0 // Coinbase=
 transactions are already normalized</span><span style=3D"background-color:=
rgba(255,255,255,0)"><font face=3D"monospace, monospace"><br></font></span>=
</div><div><span style=3D"background-color:rgba(255,255,255,0)"><font face=
=3D"monospace, monospace">=C2=A0 if (!tx.IsCoinbase())</font></span></div><=
div><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"mono=
space, monospace">=C2=A0 {</font></span></div><div><span style=3D"backgroun=
d-color:rgba(255,255,255,0)"><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 foreach(CTxIn in : tx.vin)</font></span></div><div><span style=3D"backg=
round-color:rgba(255,255,255,0)"><font face=3D"monospace, monospace">=C2=A0=
 =C2=A0 {</font></span></div><div><span style=3D"font-family:monospace,mono=
space">=C2=A0 =C2=A0 =C2=A0 if (!ReplacePrevoutHashWithNormalizedHash(in.pr=
evout))</span></div><div><span style=3D"font-family:monospace,monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 throw NormalizationError(&quot;Could not lookup=
 prevout&quot;);</span></div><div><span style=3D"font-family:monospace,mono=
space">=C2=A0 =C2=A0 =C2=A0 in.scriptSig.clear();</span></div><div><span st=
yle=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><span style=
=3D"background-color:rgba(255,255,255,0)"><font face=3D"monospace, monospac=
e"><br></font></span></div><div><span style=3D"font-family:monospace,monosp=
ace">=C2=A0 }</span><span style=3D"background-color:rgba(255,255,255,0)"><f=
ont face=3D"monospace, monospace"><br></font></span></div><div><span style=
=3D"font-family:monospace,monospace"><br></span></div><div><span style=3D"f=
ont-family:monospace,monospace">=C2=A0 // Serialize</span></div><div><font =
face=3D"monospace, monospace">=C2=A0=C2=A0<span style=3D"color:rgb(51,51,51=
);font-size:12px;line-height:16px;white-space:pre">CHashWriter </span><span=
 class=3D"" style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;wh=
ite-space:pre">ss</span><span style=3D"color:rgb(51,51,51);font-size:12px;l=
ine-height:16px;white-space:pre">(SER_GETHASH, </span><span class=3D"" styl=
e=3D"color:rgb(0,134,179);font-size:12px;line-height:16px;white-space:pre">=
0</span><span style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;=
white-space:pre">);</span></font></div><div><span style=3D"font-family:mono=
space,monospace">=C2=A0 ss &lt;&lt; tx;</span><br></div><div><font face=3D"=
monospace, monospace">=C2=A0 return ss.GetHash();</font></div><div><span st=
yle=3D"background-color:rgba(255,255,255,0)"><font face=3D"monospace, monos=
pace">}</font></span></div></div></div><div><br></div><div>An alternative c=
ould be (although I like the above option better):</div><div><br></div><div=
><div><div><span style=3D"background-color:rgba(255,255,255,0)"><font face=
=3D"monospace, monospace">uint256 normalized_txid(CTransaction tx, int nHei=
ght)</font></span></div></div><div><span style=3D"background-color:rgba(255=
,255,255,0)"><font face=3D"monospace, monospace">{</font></span></div><div>=
<div><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"mon=
ospace, monospace">=C2=A0 foreach(CTxIn in : tx.vin)</font></span></div><di=
v><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"monosp=
ace, monospace">=C2=A0 {</font></span></div><div><span style=3D"font-family=
:monospace,monospace">=C2=A0 =C2=A0 if (!in.prevout.IsNull() &amp;&amp; !Re=
placePrevoutHashWithNormalizedHash(in.prevout))</span></div><div><span styl=
e=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 =C2=A0 throw Normalizat=
ionError(&quot;Could not lookup prevout&quot;);</span></div><div><span styl=
e=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 in.scriptSig.clear();</=
span></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 }</s=
pan></div></div><div><span style=3D"font-family:monospace,monospace"><br></=
span></div><div><div><span style=3D"font-family:monospace,monospace">=C2=A0=
 // Serialize</span></div><div><font face=3D"monospace, monospace">=C2=A0=
=C2=A0<span style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;wh=
ite-space:pre">CHashWriter </span><span class=3D"" style=3D"color:rgb(51,51=
,51);font-size:12px;line-height:16px;white-space:pre">ss</span><span style=
=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">(S=
ER_GETHASH, </span><span class=3D"" style=3D"color:rgb(0,134,179);font-size=
:12px;line-height:16px;white-space:pre">0</span><span style=3D"color:rgb(51=
,51,51);font-size:12px;line-height:16px;white-space:pre">);</span></font></=
div></div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb=
(51,51,51);font-size:12px;line-height:16px;white-space:pre"><br></span></fo=
nt></div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(=
51,51,51);font-size:12px;line-height:16px;white-space:pre">  if (tx.IsCoinb=
ase())</span></font></div><div><font face=3D"monospace, monospace"><span st=
yle=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre"=
>    </span></font><span style=3D"font-size:12px;line-height:16px;white-spa=
ce:pre;color:rgb(51,51,51);font-family:monospace,monospace">ss &lt;&lt; nHe=
ight;</span></div><div><span style=3D"font-size:12px;line-height:16px;white=
-space:pre;color:rgb(51,51,51);font-family:monospace,monospace">  // or:</s=
pan></div><div><font color=3D"#333333" face=3D"monospace, monospace"><span =
style=3D"font-size:12px;line-height:16px;white-space:pre">  // </span></fon=
t><span style=3D"color:rgb(51,51,51);font-family:monospace,monospace;font-s=
ize:12px;line-height:16px;white-space:pre">ss &lt;&lt; (tx.IsCoinbase() ? n=
Height : 0);</span></div><div><span style=3D"color:rgb(51,51,51);font-famil=
y:monospace,monospace;font-size:12px;line-height:16px;white-space:pre"><br>=
</span></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 ss=
 &lt;&lt; tx;</span><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 return ss.GetHash();</font></div><div><span style=3D"background-color:r=
gba(255,255,255,0)"><font face=3D"monospace, monospace">}</font></span></di=
v></div></div></div></div>

--001a113a0528a7e73505166eb90c--