mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
wallet: account for issuances during coin selection
Prior to coin selection we need to indicate that the issuances will take extra space, otherwise we may fail to select enough coins to cover our fees, triggering the new "fee needed exceeds fees available" assertion.
This commit is contained in:
parent
3c896b11e0
commit
e5e3ec2700
2 changed files with 52 additions and 0 deletions
|
|
@ -1080,6 +1080,28 @@ bool CWallet::CreateTransactionInternal(
|
|||
// the blinding logic.
|
||||
coin_selection_params.tx_noinputs_size += 70 + 66 +(MAX_RANGEPROOF_SIZE + DEFAULT_SURJECTIONPROOF_SIZE + WITNESS_SCALE_FACTOR - 1)/WITNESS_SCALE_FACTOR;
|
||||
}
|
||||
// If we are going to issue an asset, add the issuance data to the noinputs_size so that
|
||||
// we allocate enough coins for them.
|
||||
if (issuance_details) {
|
||||
size_t issue_count = 0;
|
||||
for (unsigned int i = 0; i < txNew.vout.size(); i++) {
|
||||
if (txNew.vout[i].nAsset.IsExplicit() && txNew.vout[i].nAsset.GetAsset() == CAsset(uint256S("1"))) {
|
||||
issue_count++;
|
||||
} else if (txNew.vout[i].nAsset.IsExplicit() && txNew.vout[i].nAsset.GetAsset() == CAsset(uint256S("2"))) {
|
||||
issue_count++;
|
||||
}
|
||||
}
|
||||
if (issue_count > 0) {
|
||||
// Allocate space for blinding nonce, entropy, and whichever of nAmount/nInflationKeys is null
|
||||
coin_selection_params.tx_noinputs_size += 2 * 32 + 2 * (2 - issue_count);
|
||||
}
|
||||
// Allocate non-null nAmount/nInflationKeys and rangeproofs
|
||||
if (issuance_details->blind_issuance) {
|
||||
coin_selection_params.tx_noinputs_size += issue_count * (33 * WITNESS_SCALE_FACTOR + MAX_RANGEPROOF_SIZE + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
|
||||
} else {
|
||||
coin_selection_params.tx_noinputs_size += issue_count * 9;
|
||||
}
|
||||
}
|
||||
|
||||
// Include the fees for things that aren't inputs, excluding the change output
|
||||
const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,36 @@ class WalletCtTest(BitcoinTestFramework):
|
|||
amt = satoshi_round(Decimal(amt - Decimal(0.0005)))
|
||||
self.test_send(amt, 1, 2, True)
|
||||
|
||||
addresses = [ self.nodes[1].getnewaddress() for i in range(15) ] \
|
||||
+ [ self.nodes[2].getnewaddress() for i in range(15) ]
|
||||
txid = self.nodes[2].sendmany(amounts={address: satoshi_round(Decimal(0.00025)) for address in addresses})
|
||||
self.log.info(f"Sent many small UTXOs to nodes 1 and 2 in {txid}")
|
||||
self.nodes[2].generate(2)
|
||||
self.sync_all()
|
||||
|
||||
self.log.info(f"Issuing some assets from node 1")
|
||||
# Try issuing assets
|
||||
amt = satoshi_round(Decimal(1))
|
||||
res1 = self.nodes[1].issueasset(amt, amt, True);
|
||||
res2 = self.nodes[1].issueasset(amt, amt, False);
|
||||
|
||||
assets = [ res1["asset"], res1["token"], res2["asset"], res2["token"] ]
|
||||
addresses = [ self.nodes[2].getnewaddress() for i in range(len(assets)) ]
|
||||
txid = self.nodes[1].sendmany(
|
||||
amounts={address: amt for address in addresses},
|
||||
output_assets={addresses[i]: assets[i] for i in range(len(assets))},
|
||||
)
|
||||
self.log.info(f"Sent them to node 2 in {txid}")
|
||||
self.nodes[1].generate(2)
|
||||
self.sync_all()
|
||||
# Send them back
|
||||
addresses = [ self.nodes[1].getnewaddress() for i in range(len(assets)) ]
|
||||
txid = self.nodes[2].sendmany(
|
||||
amounts={address: amt for address in addresses},
|
||||
output_assets={addresses[i]: assets[i] for i in range(len(assets))},
|
||||
)
|
||||
self.log.info(f"Sent them back to node 1 in {txid}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletCtTest().main()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue