static void exchangeNXTForCurrency( Transaction transaction, Account account, final long currencyId, final long rateNQT, long units) { long extraUnits = 0; long remainingAmountNQT = Math.multiplyExact(units, rateNQT); List<CurrencySellOffer> currencySellOffers = new ArrayList<>(); try (DbIterator<CurrencySellOffer> offers = CurrencySellOffer.getOffers( new ValidOffersDbClause(currencyId, rateNQT, false), 0, -1, " ORDER BY rate ASC, creation_height ASC, transaction_height ASC, transaction_index ASC ")) { for (CurrencySellOffer offer : offers) { currencySellOffers.add(offer); } } for (CurrencySellOffer offer : currencySellOffers) { if (remainingAmountNQT == 0) { break; } long curUnits = Math.min( Math.min(remainingAmountNQT / offer.getRateNQT(), offer.getSupply()), offer.getLimit()); if (curUnits == 0) { continue; } long curAmountNQT = Math.multiplyExact(curUnits, offer.getRateNQT()); extraUnits = Math.addExact(extraUnits, curUnits); remainingAmountNQT = Math.subtractExact(remainingAmountNQT, curAmountNQT); offer.decreaseLimitAndSupply(curUnits); long excess = offer.getCounterOffer().increaseSupply(curUnits); Account counterAccount = Account.getAccount(offer.getAccountId()); counterAccount.addToBalanceNQT(curAmountNQT); counterAccount.addToUnconfirmedBalanceNQT( Math.addExact( Math.multiplyExact( curUnits - excess, offer.getRateNQT() - offer.getCounterOffer().getRateNQT()), Math.multiplyExact(excess, offer.getRateNQT()))); counterAccount.addToCurrencyUnits(currencyId, -curUnits); Exchange.addExchange( transaction, currencyId, offer, offer.getAccountId(), account.getId(), curUnits); } account.addToCurrencyAndUnconfirmedCurrencyUnits(currencyId, extraUnits); account.addToBalanceNQT(-(Math.multiplyExact(units, rateNQT) - remainingAmountNQT)); account.addToUnconfirmedBalanceNQT(remainingAmountNQT); }
@Override void undoAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemExchangeBuy attachment = (Attachment.MonetarySystemExchangeBuy) transaction.getAttachment(); senderAccount.addToUnconfirmedBalanceNQT( Math.multiplyExact(attachment.getUnits(), attachment.getRateNQT())); }
static void removeOffer(CurrencyBuyOffer buyOffer) { CurrencySellOffer sellOffer = buyOffer.getCounterOffer(); CurrencyBuyOffer.remove(buyOffer); CurrencySellOffer.remove(sellOffer); Account account = Account.getAccount(buyOffer.getAccountId()); account.addToUnconfirmedBalanceNQT( Math.multiplyExact(buyOffer.getSupply(), buyOffer.getRateNQT())); account.addToUnconfirmedCurrencyUnits(buyOffer.getCurrencyId(), sellOffer.getSupply()); }
@Override boolean applyAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemExchangeBuy attachment = (Attachment.MonetarySystemExchangeBuy) transaction.getAttachment(); if (senderAccount.getUnconfirmedBalanceNQT() >= Math.multiplyExact(attachment.getUnits(), attachment.getRateNQT())) { senderAccount.addToUnconfirmedBalanceNQT( -Math.multiplyExact(attachment.getUnits(), attachment.getRateNQT())); return true; } return false; }
@Override void undoAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemPublishExchangeOffer attachment = (Attachment.MonetarySystemPublishExchangeOffer) transaction.getAttachment(); senderAccount.addToUnconfirmedBalanceNQT( Math.multiplyExact(attachment.getInitialBuySupply(), attachment.getBuyRateNQT())); Currency currency = Currency.getCurrency(attachment.getCurrencyId()); if (currency != null) { senderAccount.addToUnconfirmedCurrencyUnits( attachment.getCurrencyId(), attachment.getInitialSellSupply()); } }
@Override boolean applyAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemReserveIncrease attachment = (Attachment.MonetarySystemReserveIncrease) transaction.getAttachment(); Currency currency = Currency.getCurrency(attachment.getCurrencyId()); if (senderAccount.getUnconfirmedBalanceNQT() >= Math.multiplyExact( currency.getReserveSupply(), attachment.getAmountPerUnitNQT())) { senderAccount.addToUnconfirmedBalanceNQT( -Math.multiplyExact(currency.getReserveSupply(), attachment.getAmountPerUnitNQT())); return true; } return false; }
@Override boolean applyAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemPublishExchangeOffer attachment = (Attachment.MonetarySystemPublishExchangeOffer) transaction.getAttachment(); if (senderAccount.getUnconfirmedBalanceNQT() >= Math.multiplyExact( attachment.getInitialBuySupply(), attachment.getBuyRateNQT()) && senderAccount.getUnconfirmedCurrencyUnits(attachment.getCurrencyId()) >= attachment.getInitialSellSupply()) { senderAccount.addToUnconfirmedBalanceNQT( -Math.multiplyExact(attachment.getInitialBuySupply(), attachment.getBuyRateNQT())); senderAccount.addToUnconfirmedCurrencyUnits( attachment.getCurrencyId(), -attachment.getInitialSellSupply()); return true; } return false; }
@Override void undoAttachmentUnconfirmed(Transaction transaction, Account senderAccount) { Attachment.MonetarySystemReserveIncrease attachment = (Attachment.MonetarySystemReserveIncrease) transaction.getAttachment(); long reserveSupply; Currency currency = Currency.getCurrency(attachment.getCurrencyId()); if (currency != null) { reserveSupply = currency.getReserveSupply(); } else { // currency must have been deleted, get reserve supply from the original issuance // transaction Transaction currencyIssuance = Nxt.getBlockchain().getTransaction(attachment.getCurrencyId()); Attachment.MonetarySystemCurrencyIssuance currencyIssuanceAttachment = (Attachment.MonetarySystemCurrencyIssuance) currencyIssuance.getAttachment(); reserveSupply = currencyIssuanceAttachment.getReserveSupply(); } senderAccount.addToUnconfirmedBalanceNQT( Math.multiplyExact(reserveSupply, attachment.getAmountPerUnitNQT())); }