mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge ElementsProject/elements#1014: Fix crash when creating large inputs
f7e1fb6708blind: add functional test that attempting to spend more than 256 inputs fails "gracefully" (Andrew Poelstra)ba538cbe2ablind.cpp: refuse to create surjection proofs that would trigger an assertation failure (Andrew Poelstra) Pull request description: There isn't really any reasonable way to recover from this situation but we can at least gracefully fail instead of triggering an assertation failure. Fixes #979 Fixes #880 ACKs for top commit: gwillen: utACKf7e1fb6. Tree-SHA512: 6f95732964503e5ac6fc85fd6b45958f1b1719b1f9ecf3d6295d571489112837cdb4429a02a389da82e8d5fcd55527241cba50bceff00bb4facd8be037c7dcab
This commit is contained in:
commit
d973e1105d
2 changed files with 38 additions and 0 deletions
|
|
@ -199,6 +199,15 @@ bool SurjectOutput(CTxOutWitness& txoutwit, const std::vector<secp256k1_fixed_as
|
|||
secp256k1_surjectionproof proof;
|
||||
secp256k1_fixed_asset_tag tag;
|
||||
memcpy(&tag, asset.begin(), 32);
|
||||
// FIXME [hardfork] Elements currently cannot handle surjection proofs on transactions
|
||||
// with more than 256 inputs. The Elements verification code will always try to give
|
||||
// secp-zkp the complete list of inputs, and if this exceeds 256 then surjectionproof_verify
|
||||
// will always return false, so there is no way to work around this situation at signing time
|
||||
if (surjection_targets.size() > SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS) {
|
||||
// We must return false here to avoid triggering an assertation within
|
||||
// secp256k1_surjectionproof_initialize on the next line.
|
||||
return false;
|
||||
}
|
||||
// Find correlation between asset tag and listed input tags
|
||||
if (secp256k1_surjectionproof_initialize(secp256k1_blind_context, &proof, &input_index, &surjection_targets[0], surjection_targets.size(), nInputsToSelect, &tag, 100, randseed) == 0) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
self.test_address_reuse()
|
||||
self.test_option_subtract_fee_from_outputs()
|
||||
self.test_subtract_fee_with_presets()
|
||||
self.test_surjectionproof_many_inputs()
|
||||
|
||||
def test_change_position(self):
|
||||
"""Ensure setting changePosition in fundraw with an exact match is handled properly."""
|
||||
|
|
@ -967,5 +968,33 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
signedtx = self.nodes[0].signrawtransactionwithwallet(blindedtx)
|
||||
self.nodes[0].sendrawtransaction(signedtx['hex'])
|
||||
|
||||
def test_surjectionproof_many_inputs(self):
|
||||
self.log.info("Test fundrawtx with more than 256 inputs")
|
||||
|
||||
self.nodes[0].createwallet("surjection")
|
||||
wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
|
||||
recipient = self.nodes[0].get_wallet_rpc("surjection")
|
||||
|
||||
# Make 500 0.1 BTC outputs...
|
||||
for j in range(0, 10):
|
||||
outputs = {}
|
||||
for i in range(0, 50):
|
||||
outputs[recipient.getnewaddress()] = 0.1
|
||||
wallet.sendmany("", outputs)
|
||||
self.nodes[0].generate(10)
|
||||
|
||||
# ...and try to send them all in one transaction
|
||||
# This should fail but we should not see an assertation failure.
|
||||
rawtx = recipient.createrawtransaction([], {wallet.getnewaddress(): 49.99})
|
||||
assert_raises_rpc_error(-4, "Unable to blind the transaction properly. This should not happen.", recipient.fundrawtransaction, rawtx)
|
||||
|
||||
# Try to send them across two transactions. This should succeed.
|
||||
rawtx = recipient.createrawtransaction([], {wallet.getnewaddress(): 24.99})
|
||||
for i in range(0, 2):
|
||||
fundedtx = recipient.fundrawtransaction(rawtx)
|
||||
blindedtx = recipient.blindrawtransaction(fundedtx['hex'])
|
||||
signedtx = recipient.signrawtransactionwithwallet(blindedtx)
|
||||
self.nodes[0].sendrawtransaction(signedtx['hex'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
RawTransactionsTest().main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue