static void exchangeCurrencyForNXT( Transaction transaction, Account account, final long currencyId, final long rateNQT, long units) { long extraAmountNQT = 0; long remainingUnits = units; List<CurrencyBuyOffer> currencyBuyOffers = new ArrayList<>(); try (DbIterator<CurrencyBuyOffer> offers = CurrencyBuyOffer.getOffers( new ValidOffersDbClause(currencyId, rateNQT, true), 0, -1, " ORDER BY rate DESC, creation_height ASC, transaction_height ASC, transaction_index ASC ")) { for (CurrencyBuyOffer offer : offers) { currencyBuyOffers.add(offer); } } for (CurrencyBuyOffer offer : currencyBuyOffers) { if (remainingUnits == 0) { break; } long curUnits = Math.min(Math.min(remainingUnits, offer.getSupply()), offer.getLimit()); long curAmountNQT = Math.multiplyExact(curUnits, offer.getRateNQT()); extraAmountNQT = Math.addExact(extraAmountNQT, curAmountNQT); remainingUnits = Math.subtractExact(remainingUnits, curUnits); offer.decreaseLimitAndSupply(curUnits); long excess = offer.getCounterOffer().increaseSupply(curUnits); Account counterAccount = Account.getAccount(offer.getAccountId()); counterAccount.addToBalanceNQT(-curAmountNQT); counterAccount.addToCurrencyUnits(currencyId, curUnits); counterAccount.addToUnconfirmedCurrencyUnits(currencyId, excess); Exchange.addExchange( transaction, currencyId, offer, account.getId(), offer.getAccountId(), curUnits); } account.addToBalanceAndUnconfirmedBalanceNQT(extraAmountNQT); account.addToCurrencyUnits(currencyId, -(units - remainingUnits)); account.addToUnconfirmedCurrencyUnits(currencyId, remainingUnits); }
static { Nxt.getBlockchainProcessor() .addListener( block -> { if (block.getHeight() <= Constants.MONETARY_SYSTEM_BLOCK) { return; } List<CurrencyBuyOffer> expired = new ArrayList<>(); try (DbIterator<CurrencyBuyOffer> offers = CurrencyBuyOffer.getOffers( new DbClause.IntClause("expiration_height", block.getHeight()), 0, -1)) { for (CurrencyBuyOffer offer : offers) { expired.add(offer); } } expired.forEach(CurrencyExchangeOffer::removeOffer); }, BlockchainProcessor.Event.AFTER_BLOCK_APPLY); }