MCPcopy Create free account
hub / github.com/ElementsProject/elements / FillInputToWeight

Function FillInputToWeight

src/wallet/spend.cpp:86–127  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

84}
85
86bool FillInputToWeight(CMutableTransaction& mtx, size_t nIn, int64_t target_weight)
87{
88 assert(mtx.vin[nIn].scriptSig.empty());
89 assert(mtx.witness.vtxinwit[nIn].scriptWitness.IsNull());
90
91 int64_t txin_weight = GetTransactionInputWeight(CTransaction(mtx), nIn);
92
93 // Do nothing if the weight that should be added is less than the weight that already exists
94 if (target_weight < txin_weight) {
95 return false;
96 }
97 if (target_weight == txin_weight) {
98 return true;
99 }
100
101 // Subtract current txin weight, which should include empty witness stack
102 int64_t add_weight = target_weight - txin_weight;
103 assert(add_weight > 0);
104
105 // We will want to subtract the size of the Compact Size UInt that will also be serialized.
106 // However doing so when the size is near a boundary can result in a problem where it is not
107 // possible to have a stack element size and combination to exactly equal a target.
108 // To avoid this possibility, if the weight to add is less than 10 bytes greater than
109 // a boundary, the size will be split so that 2/3rds will be in one stack element, and
110 // the remaining 1/3rd in another. Using 3rds allows us to avoid additional boundaries.
111 // 10 bytes is used because that accounts for the maximum size. This does not need to be super precise.
112 if ((add_weight >= 253 && add_weight < 263)
113 || (add_weight > std::numeric_limits<uint16_t>::max() && add_weight <= std::numeric_limits<uint16_t>::max() + 10)
114 || (add_weight > std::numeric_limits<uint32_t>::max() && add_weight <= std::numeric_limits<uint32_t>::max() + 10)) {
115 int64_t first_weight = add_weight / 3;
116 add_weight -= first_weight;
117
118 first_weight -= GetSizeOfCompactSize(first_weight);
119 mtx.witness.vtxinwit[nIn].scriptWitness.stack.emplace(mtx.witness.vtxinwit[nIn].scriptWitness.stack.end(), first_weight, 0);
120 }
121
122 add_weight -= GetSizeOfCompactSize(add_weight);
123 mtx.witness.vtxinwit[nIn].scriptWitness.stack.emplace(mtx.witness.vtxinwit[nIn].scriptWitness.stack.end(), add_weight, 0);
124 assert(GetTransactionInputWeight(CTransaction(mtx), nIn) == target_weight);
125
126 return true;
127}
128
129int CalculateMaximumSignedInputSize(const CTxOut& txout, const SigningProvider* provider, bool use_max_sig) {
130 CMutableTransaction txn;

Callers 3

DummySignTxMethod · 0.85
TestFillInputToWeightFunction · 0.85
BOOST_FIXTURE_TEST_CASEFunction · 0.85

Calls 6

GetSizeOfCompactSizeFunction · 0.85
CTransactionClass · 0.50
emptyMethod · 0.45
IsNullMethod · 0.45
endMethod · 0.45

Tested by 2

TestFillInputToWeightFunction · 0.68
BOOST_FIXTURE_TEST_CASEFunction · 0.68