MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ProduceInput

Method ProduceInput

src/script/miniscript.h:1247–1492  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1245
1246 template<typename Ctx>
1247 internal::InputResult ProduceInput(const Ctx& ctx) const {
1248 using namespace internal;
1249
1250 // Internal function which is invoked for every tree node, constructing satisfaction/dissatisfactions
1251 // given those of its subnodes.
1252 auto helper = [&ctx](const Node& node, std::span<InputResult> subres) -> InputResult {
1253 switch (node.fragment) {
1254 case Fragment::PK_K: {
1255 std::vector<unsigned char> sig;
1256 Availability avail = ctx.Sign(node.keys[0], sig);
1257 return {ZERO, InputStack(std::move(sig)).SetWithSig().SetAvailable(avail)};
1258 }
1259 case Fragment::PK_H: {
1260 std::vector<unsigned char> key = ctx.ToPKBytes(node.keys[0]), sig;
1261 Availability avail = ctx.Sign(node.keys[0], sig);
1262 return {ZERO + InputStack(key), (InputStack(std::move(sig)).SetWithSig() + InputStack(key)).SetAvailable(avail)};
1263 }
1264 case Fragment::MULTI_A: {
1265 // sats[j] represents the best stack containing j valid signatures (out of the first i keys).
1266 // In the loop below, these stacks are built up using a dynamic programming approach.
1267 std::vector<InputStack> sats = Vector(EMPTY);
1268 for (size_t i = 0; i < node.keys.size(); ++i) {
1269 // Get the signature for the i'th key in reverse order (the signature for the first key needs to
1270 // be at the top of the stack, contrary to CHECKMULTISIG's satisfaction).
1271 std::vector<unsigned char> sig;
1272 Availability avail = ctx.Sign(node.keys[node.keys.size() - 1 - i], sig);
1273 // Compute signature stack for just this key.
1274 auto sat = InputStack(std::move(sig)).SetWithSig().SetAvailable(avail);
1275 // Compute the next sats vector: next_sats[0] is a copy of sats[0] (no signatures). All further
1276 // next_sats[j] are equal to either the existing sats[j] + ZERO, or sats[j-1] plus a signature
1277 // for the current (i'th) key. The very last element needs all signatures filled.
1278 std::vector<InputStack> next_sats;
1279 next_sats.push_back(sats[0] + ZERO);
1280 for (size_t j = 1; j < sats.size(); ++j) next_sats.push_back((sats[j] + ZERO) | (std::move(sats[j - 1]) + sat));
1281 next_sats.push_back(std::move(sats[sats.size() - 1]) + std::move(sat));
1282 // Switch over.
1283 sats = std::move(next_sats);
1284 }
1285 // The dissatisfaction consists of as many empty vectors as there are keys, which is the same as
1286 // satisfying 0 keys.
1287 auto& nsat{sats[0]};
1288 CHECK_NONFATAL(node.k != 0);
1289 assert(node.k < sats.size());
1290 return {std::move(nsat), std::move(sats[node.k])};
1291 }
1292 case Fragment::MULTI: {
1293 // sats[j] represents the best stack containing j valid signatures (out of the first i keys).
1294 // In the loop below, these stacks are built up using a dynamic programming approach.
1295 // sats[0] starts off being {0}, due to the CHECKMULTISIG bug that pops off one element too many.
1296 std::vector<InputStack> sats = Vector(ZERO);
1297 for (size_t i = 0; i < node.keys.size(); ++i) {
1298 std::vector<unsigned char> sig;
1299 Availability avail = ctx.Sign(node.keys[i], sig);
1300 // Compute signature stack for just the i'th key.
1301 auto sat = InputStack(std::move(sig)).SetWithSig().SetAvailable(avail);
1302 // Compute the next sats vector: next_sats[0] is a copy of sats[0] (no signatures). All further
1303 // next_sats[j] are equal to either the existing sats[j], or sats[j-1] plus a signature for the
1304 // current (i'th) key. The very last element needs all signatures filled.

Callers

nothing calls this directly

Calls 15

InputStackClass · 0.85
VectorFunction · 0.85
SignMethod · 0.45
ToPKBytesMethod · 0.45
sizeMethod · 0.45
push_backMethod · 0.45
CheckOlderMethod · 0.45
CheckAfterMethod · 0.45
SatSHA256Method · 0.45
SatRIPEMD160Method · 0.45
SatHASH256Method · 0.45
SatHASH160Method · 0.45

Tested by

no test coverage detected