Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check burning man receiver address validity #7203

Merged

Conversation

stejbac
Copy link
Contributor

@stejbac stejbac commented Jul 15, 2024

Set the burn cap of a candidate to zero if he has an invalid receiver address, that is, one that bitcoinj cannot parse. This prevents trade protocol failure when creating the DPT, by making such BM inactive and distributing their shares to the other BM. (Setting the burn cap to zero is a little more robust than simply filtering out such candidates, as BurningManService handles subsequent share redistribution better than DelayedPayoutTxReceiverService or BtcFeeReceiverService.

While this case should normally never occur, due to UI validation of the custom receiver address, there are at least two ways a BM could invalidate his own receiver address if so inclined:

  1. He could simply bypass the UI validation;
  2. He could manually create a compensation issuance tx with a change address type unrecognised by bitcoinj, such as P2TR, as the address field is pulled straight from the RPC JSON by each full DAO node.

Thus, it is necessary to check both change and custom addresses.

--

This PR additionally does a couple of minor optimisations to BurningManService, fixes nondeterministic receiver address selection in the edge case of multiple accepted compensation proposals by the same candidate in the same cycle, and cleans up redundant date checks for the activation of fixes for #6699 and bisq-network/proposals#412.

None of the changes should alter the candidate burn shares or receiver addresses, except in possible future edge cases where the addresses would be nondeterministic or invalid, resulting in DPT creation/validation errors anyway (and thus failure to open the trade). So an activation date for these changes shouldn't be necessary.

Avoid streaming over the entire proposals list to find a matching txId,
for every 'Issuance' & 'CompensationProposal' pair used to construct and
add a compensation model to the burn output model of each candidate.
Instead, stream over the proposals list once, doing lookups by txId of
each matching issuance, which uses the TreeMap 'DaoState.issuanceMap',
thereby taking O(n*log(n)) time.
This avoids needless hashing & equality comparisons of instances of
'BurningManCandidate', which are quite large mutable objects (so should
probably use reference equality anyway, and not be used as keys).

Also rearrange a couple of (package) private methods.
Handle the exceptional case of a receiver address chosen from a cycle
where the candidate somehow got more than one compensation proposal
accepted. Either the last custom address or first issuance change
address is supposed to be chosen for the receiver address, but in case
of a tie at that vote result height, take the address that comes
first in lexicographic order.
These are both redundant now and will always return true. Also add a
missing past check for Proposal 412 activation to 'RefundManager',
instead of just defaulting to the current date, in case of any very old
disputes involving DPTs created prior to the activation.
Set the burn cap of a candidate to zero if he has an invalid receiver
address, that is, one that bitcoinj cannot parse. This prevents trade
failure when creating the DPT, by making such BM inactive and
distributing their share to the other BM. (Setting the burn cap to zero
is a little more robust than simply filtering out such candidates, as
'BurningManService' handles subsequent share redistribution better than
'(DelayedPayoutTx|BtcFee)ReceiverService'.)

While this case should normally never occur, due to UI validation of the
custom receiver address, there are at least two ways a BM could
invalidate his own receiver address if so inclined:

 1) He could simply bypass the UI validation;
 2) He could manually create a compensation issuance tx with a change
    address type unrecognised by bitcoinj, such as P2TR, as the address
    field is pulled straight from the RPC JSON by each full DAO node.

Thus, it is necessary to check both change and custom addresses.
HenrikJannsen
HenrikJannsen previously approved these changes Jul 16, 2024
Copy link
Collaborator

@HenrikJannsen HenrikJannsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Reject any custom receiver address which wasn't encoded as Bech32m if
the witness program version is greater than zero. These are currently
accepted by bitcoinj but are now invalid and would fail to parse if our
fork was updated to understand Bech32m, to support sending to P2TR
addresses, which the upstream version appears to. (Thus, the presence of
such malformed receivers would not be an issue at present, but might
cause complications in the future.)
@stejbac
Copy link
Contributor Author

stejbac commented Jul 18, 2024

There is another small change to BtcAddressValidator I wanted to push:

I noticed that bitcoinj allows any witness v1-v16 program (up to length 40 bytes) to be decoded from a Bech32 address, not just witness v0 (that is, p2wpkh & p2wsh). These give standard txs when used as outputs (and it doesn't look like bitcoinj would fail to validate or broadcast such txs either), though all of them apart from p2tr ScriptPubKeys would be anyone-can-spend and couldn't be spent in standard txs.

However, since Taproot was introduced, witness v1 programs and above are supposed to be encoded as Bech32m, not Bech32, so really any Segwit address that isn't witness v0 shouldn't validate unless/until our fork of bitcoinj parses them correctly as Bech32m (which is already done in the upstream version). Otherwise, there could be complications making such an upgrade.

Copy link
Collaborator

@HenrikJannsen HenrikJannsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

@alejandrogarcia83 alejandrogarcia83 added this to the v1.9.18 milestone Jul 19, 2024
Copy link
Contributor

@alejandrogarcia83 alejandrogarcia83 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

@alejandrogarcia83 alejandrogarcia83 merged commit b8e3296 into bisq-network:master Jul 19, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants