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);
  }
 long increaseSupply(long delta) {
   long excess = Math.max(Math.addExact(supply, Math.subtractExact(delta, limit)), 0);
   supply += delta - excess;
   return excess;
 }
 @Override
 public Integer minus(Integer other) {
   try {
     return new ScalableInt32(Math.subtractExact(this.value, ((ScalableInt32) other).value));
   } catch (ClassCastException e) {
     return promoteNext().minus(other);
   } catch (ArithmeticException e) {
     return promoteNext().minus(other);
   }
 }
Esempio n. 4
0
 /**
  * Returns a copy of this period with the specified period subtracted.
  *
  * <p>This operates separately on the years, months, days and the normalized time. There is no
  * further normalization beyond the normalized time.
  *
  * <p>For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days" returns "-1
  * years, 4 months and 1 day".
  *
  * <p>This instance is immutable and unaffected by this method call.
  *
  * @param amountToSubtract the period to subtract, not null
  * @return a {@code Period} based on this period with the requested period subtracted, not null
  * @throws ArithmeticException if numeric overflow occurs
  */
 public Period minus(Period amountToSubtract) {
   return create(
       Math.subtractExact(years, amountToSubtract.years),
       Math.subtractExact(months, amountToSubtract.months),
       Math.subtractExact(days, amountToSubtract.days));
 }