mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
Merge 8228521a6ee224e00be014a07df4401dc2b1cb5c into 5f4422d68dc3530c353af1f87499de1c864b60ad
This commit is contained in:
commit
9a506b3d52
@ -1202,32 +1202,50 @@ private:
|
|||||||
return {ZERO + InputStack(key), (InputStack(std::move(sig)).SetWithSig() + InputStack(key)).SetAvailable(avail)};
|
return {ZERO + InputStack(key), (InputStack(std::move(sig)).SetWithSig() + InputStack(key)).SetAvailable(avail)};
|
||||||
}
|
}
|
||||||
case Fragment::MULTI_A: {
|
case Fragment::MULTI_A: {
|
||||||
// sats[j] represents the best stack containing j valid signatures (out of the first i keys).
|
// take the first k number of valid signatures out of node.keys
|
||||||
// In the loop below, these stacks are built up using a dynamic programming approach.
|
// if number of validate signatures is less than node.k, return an empty InputStack with Availability::NO
|
||||||
std::vector<InputStack> sats = Vector(EMPTY);
|
InputStack sat_return;
|
||||||
|
unsigned int num_of_good_sigs = 0;
|
||||||
for (size_t i = 0; i < node.keys.size(); ++i) {
|
for (size_t i = 0; i < node.keys.size(); ++i) {
|
||||||
// Get the signature for the i'th key in reverse order (the signature for the first key needs to
|
|
||||||
// be at the top of the stack, contrary to CHECKMULTISIG's satisfaction).
|
|
||||||
std::vector<unsigned char> sig;
|
std::vector<unsigned char> sig;
|
||||||
Availability avail = ctx.Sign(node.keys[node.keys.size() - 1 - i], sig);
|
Availability avail = ctx.Sign(node.keys[node.keys.size() - 1 - i], sig);
|
||||||
// Compute signature stack for just this key.
|
// Compute signature stack for just this key.
|
||||||
auto sat = InputStack(std::move(sig)).SetWithSig().SetAvailable(avail);
|
auto sat = InputStack(std::move(sig)).SetWithSig().SetAvailable(avail);
|
||||||
// Compute the next sats vector: next_sats[0] is a copy of sats[0] (no signatures). All further
|
if (sat.available == Availability::YES && num_of_good_sigs < node.k) {
|
||||||
// next_sats[j] are equal to either the existing sats[j] + ZERO, or sats[j-1] plus a signature
|
++num_of_good_sigs;
|
||||||
// for the current (i'th) key. The very last element needs all signatures filled.
|
if (sat_return.available == Availability::NO) {
|
||||||
std::vector<InputStack> next_sats;
|
// need to prepend i-1 number of ZEROs to fix the boundary condition that when sat_return is Availability::NO, then the operator+ will clear the stacks when add with sat with valid stacks
|
||||||
next_sats.push_back(sats[0] + ZERO);
|
auto temp_sat = ZERO;
|
||||||
for (size_t j = 1; j < sats.size(); ++j) next_sats.push_back((sats[j] + ZERO) | (std::move(sats[j - 1]) + sat));
|
for (size_t k=0; k < i-1; ++k)
|
||||||
next_sats.push_back(std::move(sats[sats.size() - 1]) + std::move(sat));
|
temp_sat = temp_sat + ZERO;
|
||||||
// Switch over.
|
sat_return = std::move(temp_sat) + std::move(sat);
|
||||||
sats = std::move(next_sats);
|
} else {
|
||||||
|
sat_return = std::move(sat_return) + std::move(sat);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (sat.available == Availability::NO && sat_return.has_sig == false) {
|
||||||
|
// when sat is Availability::NO, sat_return should be overwritten by sat:
|
||||||
|
sat_return = std::move(sat);
|
||||||
|
} else {
|
||||||
|
sat_return = std::move(sat_return) + ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for nsat_return, it expects node.keys.size() number of ZEROs, thus adding this for loop
|
||||||
|
InputStack nsat_return;
|
||||||
|
for (size_t i = 0; i < node.keys.size(); ++i) {
|
||||||
|
nsat_return = std::move(nsat_return) + ZERO;
|
||||||
}
|
}
|
||||||
// The dissatisfaction consists of as many empty vectors as there are keys, which is the same as
|
// The dissatisfaction consists of as many empty vectors as there are keys, which is the same as
|
||||||
// satisfying 0 keys.
|
// satisfying 0 keys.
|
||||||
auto& nsat{sats[0]};
|
auto& nsat{nsat_return};
|
||||||
assert(node.k != 0);
|
assert(node.k != 0);
|
||||||
assert(node.k <= sats.size());
|
if (num_of_good_sigs < node.k)
|
||||||
return {std::move(nsat), std::move(sats[node.k])};
|
{
|
||||||
|
// this is to reset sat_return when there are not enough k numbers of valid signatures
|
||||||
|
sat_return.SetAvailable(Availability::NO);
|
||||||
|
}
|
||||||
|
return {std::move(nsat), std::move(sat_return)};
|
||||||
}
|
}
|
||||||
case Fragment::MULTI: {
|
case Fragment::MULTI: {
|
||||||
// sats[j] represents the best stack containing j valid signatures (out of the first i keys).
|
// sats[j] represents the best stack containing j valid signatures (out of the first i keys).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user