Skip to content

Commit

Permalink
implement protocol v2
Browse files Browse the repository at this point in the history
  • Loading branch information
woodser committed Sep 7, 2021
1 parent 65bcd47 commit 86f7d09
Show file tree
Hide file tree
Showing 185 changed files with 5,102 additions and 3,995 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ To bring Haveno to life, we need resources. If you have the possibility, please

![Qr code](https://raw.githubusercontent.com/haveno-dex/haveno/master/media/qrhaveno.png)

If you are using a wallet that supports Openalias (like the 'official' CLI and GUI wallets), you can simply put `[email protected]` as the "receiver" address.
If you are using a wallet that supports Openalias (like the 'official' CLI and GUI wallets), you can simply put `[email protected]` as the "receiver" address.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ configure(subprojects) {
grpcVersion = '1.25.0'
gsonVersion = '2.8.5'
guavaVersion = '28.2-jre'
moneroJavaVersion = '0.5.3'
moneroJavaVersion = '0.5.4'
httpclient5Version = '5.0'
guiceVersion = '4.2.2'
hamcrestVersion = '1.3'
Expand Down
6 changes: 3 additions & 3 deletions cli/src/main/java/bisq/cli/TradeFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private static String formatTradeData(String format,

private static final Function<TradeInfo, String> amountFormat = (t) ->
t.getOffer().getBaseCurrencyCode().equals("XMR")
? formatXmr(ParsingUtils.satoshisToXmrAtomicUnits(t.getTradeAmountAsLong()))
? formatXmr(ParsingUtils.centinerosToAtomicUnits(t.getTradeAmountAsLong()))
: formatCryptoCurrencyOfferVolume(t.getOffer().getVolume());

private static final BiFunction<TradeInfo, Boolean, String> makerTakerMinerTxFeeFormat = (t, isTaker) -> {
Expand All @@ -173,13 +173,13 @@ private static String formatTradeData(String format,
};

private static final BiFunction<TradeInfo, Boolean, String> makerTakerFeeFormat = (t, isTaker) -> {
return formatXmr(ParsingUtils.satoshisToXmrAtomicUnits(t.getTakerFeeAsLong()));
return formatXmr(ParsingUtils.centinerosToAtomicUnits(t.getTakerFeeAsLong()));
};

private static final Function<TradeInfo, String> tradeCostFormat = (t) ->
t.getOffer().getBaseCurrencyCode().equals("XMR")
? formatOfferVolume(t.getOffer().getVolume())
: formatXmr(ParsingUtils.satoshisToXmrAtomicUnits(t.getTradeAmountAsLong()));
: formatXmr(ParsingUtils.centinerosToAtomicUnits(t.getTradeAmountAsLong()));

private static final BiFunction<TradeInfo, Boolean, String> bsqReceiveAddress = (t, showBsqBuyerAddress) -> {
if (showBsqBuyerAddress) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ public Optional<AccountAgeWitness> findWitness(Offer offer) {

private Optional<AccountAgeWitness> findTradePeerWitness(Trade trade) {
if (trade instanceof ArbitratorTrade) return Optional.empty(); // TODO (woodser): arbitrator trade has two peers
TradingPeer tradingPeer = trade.getProcessModel().getTradingPeer();
TradingPeer tradingPeer = trade.getTradingPeer();
return (tradingPeer == null ||
tradingPeer.getPaymentAccountPayload() == null ||
tradingPeer.getPubKeyRing() == null) ?
Expand Down Expand Up @@ -426,7 +426,7 @@ private long getTradeLimit(Coin maxTradeLimit,
long limit = OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value;
var factor = signedBuyFactor(accountAgeCategory);
if (factor > 0) {
limit = MathUtils.roundDoubleToLong((double) maxTradeLimit.value * factor);
limit = MathUtils.roundDoubleToLong(maxTradeLimit.value * factor);
}

log.debug("limit={}, factor={}, accountAgeWitnessHash={}",
Expand Down Expand Up @@ -726,8 +726,8 @@ public void arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
public Optional<SignedWitness> traderSignAndPublishPeersAccountAgeWitness(Trade trade) {
AccountAgeWitness peersWitness = findTradePeerWitness(trade).orElse(null);
Coin tradeAmount = trade.getTradeAmount();
checkNotNull(trade.getProcessModel().getTradingPeer().getPubKeyRing(), "Peer must have a keyring");
PublicKey peersPubKey = trade.getProcessModel().getTradingPeer().getPubKeyRing().getSignaturePubKey();
checkNotNull(trade.getTradingPeer().getPubKeyRing(), "Peer must have a keyring");
PublicKey peersPubKey = trade.getTradingPeer().getPubKeyRing().getSignaturePubKey();
checkNotNull(peersWitness, "Not able to find peers witness, unable to sign for trade {}",
trade.toString());
checkNotNull(tradeAmount, "Trade amount must not be null");
Expand Down Expand Up @@ -767,15 +767,11 @@ private boolean isNotFiltered(Dispute dispute) {
boolean isFiltered = filterManager.isNodeAddressBanned(dispute.getContract().getBuyerNodeAddress()) ||
filterManager.isNodeAddressBanned(dispute.getContract().getSellerNodeAddress()) ||
filterManager.isCurrencyBanned(dispute.getContract().getOfferPayload().getCurrencyCode()) ||
filterManager.isPaymentMethodBanned(
PaymentMethod.getPaymentMethodById(dispute.getContract().getPaymentMethodId())) ||
filterManager.arePeersPaymentAccountDataBanned(dispute.getContract().getBuyerPaymentAccountPayload()) ||
filterManager.arePeersPaymentAccountDataBanned(
dispute.getContract().getSellerPaymentAccountPayload()) ||
filterManager.isWitnessSignerPubKeyBanned(
Utils.HEX.encode(dispute.getContract().getBuyerPubKeyRing().getSignaturePubKeyBytes())) ||
filterManager.isWitnessSignerPubKeyBanned(
Utils.HEX.encode(dispute.getContract().getSellerPubKeyRing().getSignaturePubKeyBytes()));
filterManager.isPaymentMethodBanned(PaymentMethod.getPaymentMethodById(dispute.getContract().getPaymentMethodId())) ||
filterManager.arePeersPaymentAccountDataBanned(dispute.getBuyerPaymentAccountPayload()) ||
filterManager.arePeersPaymentAccountDataBanned(dispute.getSellerPaymentAccountPayload()) ||
filterManager.isWitnessSignerPubKeyBanned(Utils.HEX.encode(dispute.getContract().getBuyerPubKeyRing().getSignaturePubKeyBytes())) ||
filterManager.isWitnessSignerPubKeyBanned(Utils.HEX.encode(dispute.getContract().getSellerPubKeyRing().getSignaturePubKeyBytes()));
return !isFiltered;
}

Expand All @@ -797,8 +793,8 @@ private Stream<TraderDataItem> getTraderData(Dispute dispute) {
PubKeyRing buyerPubKeyRing = dispute.getContract().getBuyerPubKeyRing();
PubKeyRing sellerPubKeyRing = dispute.getContract().getSellerPubKeyRing();

PaymentAccountPayload buyerPaymentAccountPaload = dispute.getContract().getBuyerPaymentAccountPayload();
PaymentAccountPayload sellerPaymentAccountPaload = dispute.getContract().getSellerPaymentAccountPayload();
PaymentAccountPayload buyerPaymentAccountPaload = dispute.getBuyerPaymentAccountPayload();
PaymentAccountPayload sellerPaymentAccountPaload = dispute.getSellerPaymentAccountPayload();

TraderDataItem buyerData = findWitness(buyerPaymentAccountPaload, buyerPubKeyRing)
.map(witness -> new TraderDataItem(
Expand Down Expand Up @@ -913,8 +909,7 @@ public Set<SignedWitness> getUnsignedSignerPubKeys() {
public boolean isSignWitnessTrade(Trade trade) {
checkNotNull(trade, "trade must not be null");
checkNotNull(trade.getOffer(), "offer must not be null");
Contract contract = checkNotNull(trade.getContract());
PaymentAccountPayload sellerPaymentAccountPayload = contract.getSellerPaymentAccountPayload();
PaymentAccountPayload sellerPaymentAccountPayload = trade.getSeller().getPaymentAccountPayload();
AccountAgeWitness myWitness = getMyWitness(sellerPaymentAccountPayload);

getAccountAgeWitnessUtils().witnessDebugLog(trade, myWitness);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ public void witnessDebugLog(Trade trade, @Nullable AccountAgeWitness myWitness)
// Log to find why accounts sometimes don't get signed as expected
// TODO: Demote to debug or remove once account signing is working ok
checkNotNull(trade.getContract());
checkNotNull(trade.getContract().getBuyerPaymentAccountPayload());
checkNotNull(trade.getBuyer().getPaymentAccountPayload());
boolean checkingSignTrade = true;
boolean isBuyer = trade.getContract().isMyRoleBuyer(keyRing.getPubKeyRing());
AccountAgeWitness witness = myWitness;
if (witness == null) {
witness = isBuyer ?
accountAgeWitnessService.getMyWitness(trade.getContract().getBuyerPaymentAccountPayload()) :
accountAgeWitnessService.getMyWitness(trade.getContract().getSellerPaymentAccountPayload());
accountAgeWitnessService.getMyWitness(trade.getBuyer().getPaymentAccountPayload()) :
accountAgeWitnessService.getMyWitness(trade.getSeller().getPaymentAccountPayload());
checkingSignTrade = false;
}
boolean isSignWitnessTrade = accountAgeWitnessService.accountIsSigner(witness) &&
Expand All @@ -157,9 +157,9 @@ public void witnessDebugLog(Trade trade, @Nullable AccountAgeWitness myWitness)
"\nisSignWitnessTrade: {}",
trade.getId(),
isBuyer,
getWitnessDebugLog(trade.getContract().getBuyerPaymentAccountPayload(),
getWitnessDebugLog(trade.getBuyer().getPaymentAccountPayload(),
trade.getContract().getBuyerPubKeyRing()),
getWitnessDebugLog(trade.getContract().getSellerPaymentAccountPayload(),
getWitnessDebugLog(trade.getSeller().getPaymentAccountPayload(),
trade.getContract().getSellerPubKeyRing()),
checkingSignTrade, // Following cases added to use same logic as in seller signing check
accountAgeWitnessService.accountIsSigner(witness),
Expand Down
1 change: 0 additions & 1 deletion core/src/main/java/bisq/core/api/CoreTradesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ void takeOffer(Offer offer,
tradeManager.onTakeOffer(offer.getAmount(),
takeOfferModel.getTxFeeFromFeeService(),
takeOfferModel.getTakerFee(),
offer.getPrice().getValue(),
takeOfferModel.getFundsNeededForTrade(),
offer,
paymentAccountId,
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/bisq/core/api/model/TradeInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public static TradeInfo toTradeInfo(Trade trade, String role) {
contract.isBuyerMakerAndSellerTaker(),
contract.getMakerAccountId(),
contract.getTakerAccountId(),
toPaymentAccountPayloadInfo(contract.getMakerPaymentAccountPayload()),
toPaymentAccountPayloadInfo(contract.getTakerPaymentAccountPayload()),
toPaymentAccountPayloadInfo(trade.getMaker().getPaymentAccountPayload()),
toPaymentAccountPayloadInfo(trade.getTaker().getPaymentAccountPayload()),
contract.getMakerPayoutAddressString(),
contract.getTakerPayoutAddressString(),
contract.getLockTime());
Expand All @@ -127,8 +127,8 @@ public static TradeInfo toTradeInfo(Trade trade, String role) {
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
.withTakerFeeTxId(trade.getTakerFeeTxId())
.withMakerDepositTxId(trade.getMakerDepositTxId())
.withTakerDepositTxId(trade.getTakerDepositTxId())
.withMakerDepositTxId(trade.getMaker().getDepositTxHash())
.withTakerDepositTxId(trade.getTaker().getDepositTxHash())
.withPayoutTxId(trade.getPayoutTxId())
.withTradeAmountAsLong(trade.getTradeAmountAsLong())
.withTradePrice(trade.getTradePrice().getValue())
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/bisq/core/app/WalletAppSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,10 @@ void setRejectedTxErrorMessageHandler(Consumer<String> rejectedTxErrorMessageHan
.filter(trade -> trade.getOffer() != null)
.forEach(trade -> {
String details = null;
if (txId.equals(trade.getMakerDepositTxId())) {
if (txId.equals(trade.getMaker().getDepositTxHash())) {
details = Res.get("popup.warning.trade.txRejected.deposit"); // TODO (woodser): txRejected.maker_deposit, txRejected.taker_deposit
}
if (txId.equals(trade.getTakerDepositTxId())) {
if (txId.equals(trade.getTaker().getDepositTxHash())) {
details = Res.get("popup.warning.trade.txRejected.deposit");
}
if (txId.equals(trade.getOffer().getOfferFeePaymentTxId()) || txId.equals(trade.getTakerFeeTxId())) {
Expand Down
71 changes: 40 additions & 31 deletions core/src/main/java/bisq/core/btc/Balances.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

package bisq.core.btc;

import bisq.common.UserThread;
import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.support.dispute.Dispute;
Expand All @@ -26,30 +28,21 @@
import bisq.core.trade.TradeManager;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager;

import bisq.common.UserThread;

import org.bitcoinj.core.Coin;

import javax.inject.Inject;

import bisq.core.util.ParsingUtils;
import bisq.network.p2p.P2PService;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

import javafx.collections.ListChangeListener;

import java.math.BigInteger;

import java.util.List;

import javax.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;



import monero.wallet.model.MoneroAccount;
import monero.wallet.model.MoneroOutputQuery;
import monero.wallet.model.MoneroOutputWallet;
import monero.wallet.model.MoneroWalletListener;
import org.bitcoinj.core.Coin;

@Slf4j
public class Balances {
Expand Down Expand Up @@ -98,29 +91,45 @@ private void updateBalance() {
// Need to delay a bit to get the balances correct
UserThread.execute(() -> {
updateAvailableBalance();
updateReservedBalance();
updateLockedBalance();
updateReservedBalance();
});
}

// TODO (woodser): currently reserved balance = reserved for trade (excluding multisig) and locked balance = txs with < 10 confirmations
// TODO (woodser): balances being set as Coin from BigInteger.longValue(), which can lose precision. should be in centineros for consistency with the rest of the application

private void updateAvailableBalance() {
availableBalance.set(Coin.valueOf(xmrWalletService.getWallet().getUnlockedBalance(0).longValue()));
}

private void updateReservedBalance() {
BigInteger sum = new BigInteger("0");
List<MoneroAccount> accounts = xmrWalletService.getWallet().getAccounts();
for (MoneroAccount account : accounts) {
if (account.getIndex() != 0) sum = sum.add(account.getBalance());
}
reservedBalance.set(Coin.valueOf(sum.longValue()));
availableBalance.set(Coin.valueOf(xmrWalletService.getWallet().getUnlockedBalance(0).longValueExact()));
}

private void updateLockedBalance() {
BigInteger balance = xmrWalletService.getWallet().getBalance(0);
BigInteger unlockedBalance = xmrWalletService.getWallet().getUnlockedBalance(0);
lockedBalance.set(Coin.valueOf(balance.subtract(unlockedBalance).longValue()));
lockedBalance.set(Coin.valueOf(balance.subtract(unlockedBalance).longValueExact()));
}

private void updateReservedBalance() {

// add frozen input amounts
Coin sum = Coin.valueOf(0);
List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false));
for (MoneroOutputWallet frozenOutput : frozenOutputs) sum = sum.add(Coin.valueOf(frozenOutput.getAmount().longValueExact()));

// add multisig deposit amounts
List<Trade> openTrades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
for (Trade trade : openTrades) {
if (trade.getContract() == null) continue;
Long reservedAmt;
OfferPayload offerPayload = trade.getContract().getOfferPayload();
if (trade.getArbitratorNodeAddress().equals(P2PService.getMyNodeAddress())) { // TODO (woodser): this only works if node address does not change
reservedAmt = offerPayload.getAmount() + offerPayload.getBuyerSecurityDeposit() + offerPayload.getSellerSecurityDeposit(); // arbitrator reserved balance is sum of amounts sent to multisig
} else {
reservedAmt = trade.getContract().isMyRoleBuyer(tradeManager.getKeyRing().getPubKeyRing()) ? offerPayload.getBuyerSecurityDeposit() : offerPayload.getAmount() + offerPayload.getSellerSecurityDeposit();
}
sum = sum.add(Coin.valueOf(ParsingUtils.centinerosToAtomicUnits(reservedAmt).longValueExact()));
}

// set reserved balance
reservedBalance.set(sum);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@
import java.math.BigInteger;

public class XmrBalanceListener {
private Integer accountIndex;
private Integer subaddressIndex;

public XmrBalanceListener() {
}

public XmrBalanceListener(Integer accountIndex) {
this.accountIndex = accountIndex;
this.subaddressIndex = accountIndex;
}

public Integer getAccountIndex() {
return accountIndex;
public Integer getSubaddressIndex() {
return subaddressIndex;
}

public void onBalanceChanged(BigInteger balance) {
Expand Down
Loading

0 comments on commit 86f7d09

Please sign in to comment.