Skip to content

Commit 6026a0b

Browse files
committed
Merge pull request bitcoin#370 from jl2012/bip114ref
BIP114: Clarifying reference implementation
2 parents 6c71b46 + 3ef0734 commit 6026a0b

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

bip-0114.mediawiki

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,58 +133,96 @@ This BIP depends on [[bip-0141.mediawiki|BIP141]] and will be deployed by versio
133133
The idea of MAST originates from Russell O’Connor, Pieter Wuille, and [https://bitcointalk.org/index.php?topic=255145.msg2757327#msg2757327 Peter Todd].
134134

135135
== Reference Implementation ==
136-
https://github.com/jl2012/bitcoin/commit/f335cab76eb95d4f7754a718df201216a4975d8c
136+
https://github.com/jl2012/bitcoin/tree/segwit_mast
137137

138138
<source lang="cpp">
139+
//New rules apply if version byte is 1 and witness program size is 32 bytes
139140
if (witversion == 1) {
140141
if (program.size() == 32) {
142+
143+
//Witness stack must have at least 3 items
141144
if (witness.stack.size() < 3)
142145
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
143146

144-
//Script: the last witness stack item
147+
//Script is the last witness stack item
145148
scriptPubKey = CScript(witness.stack.back().begin(), witness.stack.back().end());
146149
uint256 hashScriptPubKey;
147150
CHash256().Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(hashScriptPubKey.begin());
148151

149-
//Path: the second last witness stack item; size = 32N, 0 <= N < 33
152+
//Path is the second last witness stack item
150153
std::vector<unsigned char> pathdata = witness.stack.at(witness.stack.size() - 2);
154+
155+
// Size of Path must be a multiple of 32 bytes (0 byte is allowed)
151156
if (pathdata.size() & 0x1F)
152157
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
158+
159+
// Depth of the tree is size of Path divided by 32
153160
unsigned int depth = pathdata.size() >> 5;
161+
162+
// Maximum allowed depth is 32
154163
if (depth > 32)
155164
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
156165
std::vector<uint256> path;
157166
path.resize(depth);
158167
for (unsigned int i = 0; i < depth; i++)
159168
memcpy(path[i].begin(), &pathdata[32 * i], 32);
160169

161-
//Position: the third last witness stack item; unsigned int with smallest possible value and no leading zero
170+
//Position is the third last witness stack item
162171
std::vector<unsigned char> positiondata = witness.stack.at(witness.stack.size() - 3);
172+
173+
//Position may have 4 bytes at most
163174
if (positiondata.size() > 4)
164175
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
176+
165177
uint32_t position = 0;
178+
179+
//Position is an unsigned little-endian integer with no leading zero byte
166180
if (positiondata.size() > 0) {
167181
if (positiondata.back() == 0x00)
168182
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
169183
for (size_t i = 0; i != positiondata.size(); ++i)
170184
position |= static_cast<uint32_t>(positiondata[i]) << 8 * i;
171185
}
186+
187+
//Position must not be larger than the maximum number of items allowed by the depth of tree
172188
if (depth < 32) {
173189
if (position >= (1U << depth))
174190
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
175191
}
176192

193+
//Calculate the Merkle Root and compare with the witness program
177194
uint256 root = ComputeMerkleRootFromBranch(hashScriptPubKey, path, position);
178195
if (memcmp(root.begin(), &program[0], 32))
179196
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
180197

198+
//Remaining stack items used for evaluation
181199
stack = std::vector<std::vector<unsigned char> >(witness.stack.begin(), witness.stack.end() - 3);
182-
} else {
200+
}
201+
202+
else {
203+
//Invalid if version byte is 1 but witness program size is not 32 bytes
183204
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH);
184205
}
185206
}
186207
</source>
187208

209+
Copying from <code>src/consensus/merkle.cpp</code>:
210+
<source lang="cpp">
211+
uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& vMerkleBranch, uint32_t nIndex) {
212+
uint256 hash = leaf;
213+
for (std::vector<uint256>::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) {
214+
if (nIndex & 1) {
215+
hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
216+
} else {
217+
hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
218+
}
219+
nIndex >>= 1;
220+
}
221+
return hash;
222+
}
223+
</source>
224+
225+
188226
== References ==
189227
*[[bip-0141.mediawiki|BIP141 Segregated Witness (Consensus layer)]]
190228

0 commit comments

Comments
 (0)