Merge bitcoin/bitcoin#26567: Wallet: estimate the size of signed inputs using descriptors
10546a569cwallet: accurately account for the size of the witness stack (Antoine Poinsot)9b7ec393b8wallet: use descriptor satisfaction size to estimate inputs size (Antoine Poinsot)8d870a9873script/signingprovider: introduce a MultiSigningProvider (Antoine Poinsot)fa7c46b503descriptor: introduce a method to get the satisfaction size (Antoine Poinsot)bdba7667d2miniscript: introduce a helper to get the maximum witness size (Antoine Poinsot)4ab382c2cdminiscript: make GetStackSize independent of P2WSH context (Antoine Poinsot) Pull request description: The wallet currently estimates the size of a signed input by doing a dry run of the signing logic. This is unnecessary since all outputs we can sign for can be represented by a descriptor, and we can derive the size of a satisfaction ("signature") directly from the descriptor itself. In addition, the current approach does not generalize well: dry runs of the signing logic are only possible for the most basic scripts. See for instance the discussion in #24149 around that. This introduces a method to get the maximum size of a satisfaction from a descriptor, and makes the wallet use that instead of the dry-run. ACKs for top commit: sipa: utACK10546a569cachow101: re-ACK10546a569cTree-SHA512: 43ed1529fbd30af709d903c8c5063235e8c6a03b500bc8f144273d6184e23a53edf0fea9ef898ed57d8a40d73208b5d935cc73b94a24fad3ad3c63b3b2027174
This commit is contained in:
15 files changed
+507
-206
No files matched your search
@@ -62,57 +62,6 @@ BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
|
||||
BOOST_CHECK_EQUAL(fee, check_tx(fee + 123));
|
||||
}
|
||||
|
||||
static void TestFillInputToWeight(int64_t additional_weight, std::vector<int64_t> expected_stack_sizes)
|
||||
{
|
||||
static const int64_t EMPTY_INPUT_WEIGHT = GetTransactionInputWeight(CTxIn());
|
||||
|
||||
CTxIn input;
|
||||
int64_t target_weight = EMPTY_INPUT_WEIGHT + additional_weight;
|
||||
BOOST_CHECK(FillInputToWeight(input, target_weight));
|
||||
BOOST_CHECK_EQUAL(GetTransactionInputWeight(input), target_weight);
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack.size(), expected_stack_sizes.size());
|
||||
for (unsigned int i = 0; i < expected_stack_sizes.size(); ++i) {
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack[i].size(), expected_stack_sizes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(FillInputToWeightTest, BasicTestingSetup)
|
||||
{
|
||||
{
|
||||
// Less than or equal minimum of 165 should not add any witness data
|
||||
CTxIn input;
|
||||
BOOST_CHECK(!FillInputToWeight(input, -1));
|
||||
BOOST_CHECK_EQUAL(GetTransactionInputWeight(input), 165);
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack.size(), 0);
|
||||
BOOST_CHECK(!FillInputToWeight(input, 0));
|
||||
BOOST_CHECK_EQUAL(GetTransactionInputWeight(input), 165);
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack.size(), 0);
|
||||
BOOST_CHECK(!FillInputToWeight(input, 164));
|
||||
BOOST_CHECK_EQUAL(GetTransactionInputWeight(input), 165);
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack.size(), 0);
|
||||
BOOST_CHECK(FillInputToWeight(input, 165));
|
||||
BOOST_CHECK_EQUAL(GetTransactionInputWeight(input), 165);
|
||||
BOOST_CHECK_EQUAL(input.scriptWitness.stack.size(), 0);
|
||||
}
|
||||
|
||||
// Make sure we can add at least one weight
|
||||
TestFillInputToWeight(1, {0});
|
||||
|
||||
// 1 byte compact size uint boundary
|
||||
TestFillInputToWeight(252, {251});
|
||||
TestFillInputToWeight(253, {83, 168});
|
||||
TestFillInputToWeight(262, {86, 174});
|
||||
TestFillInputToWeight(263, {260});
|
||||
|
||||
// 3 byte compact size uint boundary
|
||||
TestFillInputToWeight(65535, {65532});
|
||||
TestFillInputToWeight(65536, {21842, 43688});
|
||||
TestFillInputToWeight(65545, {21845, 43694});
|
||||
TestFillInputToWeight(65546, {65541});
|
||||
|
||||
// Note: We don't test the next boundary because of memory allocation constraints.
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(wallet_duplicated_preset_inputs_test, TestChain100Setup)
|
||||
{
|
||||
// Verify that the wallet's Coin Selection process does not include pre-selected inputs twice in a transaction.
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const override { return false; };
|
||||
bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const override { return false; }
|
||||
void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const override {}
|
||||
std::optional<int64_t> ScriptSize() const override { return {}; }
|
||||
std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
|
||||
std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(wallet_load_descriptors, TestingSetup)
|
||||
|
||||
Reference in new issue
Block a user