void createOffer(TestAccount& from, Amount const& in, Amount const& out, Ledger::pointer ledger, bool sign) { Json::Value tx_json = getCommonTransactionJson(from); tx_json[jss::TransactionType] = "OfferCreate"; tx_json[jss::TakerPays] = in.getJson(); tx_json[jss::TakerGets] = out.getJson(); STTx tx = parseTransaction(from, tx_json, sign); applyTransaction(ledger, tx, sign); }
/** Calculate the amount particular user could get through an offer. @param amount the maximum flow that is available to the taker. @param offer the offer to flow through. @param taker the person taking the offer. @return the maximum amount that can flow through this offer. */ Amounts Taker::flow (Amounts amount, Offer const& offer, Account const& taker) { // Limit taker's input by available funds less fees Amount const taker_funds (view ().accountFunds ( taker, amount.in, fhZERO_IF_FROZEN)); // Get fee rate paid by taker std::uint32_t const taker_charge_rate (rippleTransferRate (view (), taker, offer.account (), amount.in.getIssuer())); // Skip some math when there's no fee if (taker_charge_rate == QUALITY_ONE) { amount = offer.quality ().ceil_in (amount, taker_funds); } else { Amount const taker_charge (amountFromRate (taker_charge_rate)); amount = offer.quality ().ceil_in (amount, divide (taker_funds, taker_charge, taker_funds.issue ())); } // Best flow the owner can get. // Start out assuming entire offer will flow. Amounts owner_amount (amount); // Limit owner's output by available funds less fees Amount const owner_funds (view ().accountFunds ( offer.account (), owner_amount.out, fhZERO_IF_FROZEN)); // Get fee rate paid by owner std::uint32_t const owner_charge_rate (rippleTransferRate (view (), offer.account (), taker, amount.out.getIssuer())); if (owner_charge_rate == QUALITY_ONE) { // Skip some math when there's no fee owner_amount = offer.quality ().ceil_out (owner_amount, owner_funds); } else { Amount const owner_charge (amountFromRate (owner_charge_rate)); owner_amount = offer.quality ().ceil_out (owner_amount, divide (owner_funds, owner_charge, owner_funds.issue ())); } // Calculate the amount that will flow through the offer // This does not include the fees. return (owner_amount.in < amount.in) ? owner_amount : amount; }
Json::Value findPath(Ledger::pointer ledger, TestAccount const& src, TestAccount const& dest, std::vector<Currency> srcCurrencies, Amount const& dstAmount, beast::abstract_ostream& log, boost::optional<Json::Value> contextPaths) { int const level = 8; auto cache = std::make_shared<RippleLineCache>(ledger); STAmount saDstAmount; if (!amountFromJsonNoThrow(saDstAmount, dstAmount.getJson())) throw std::runtime_error( "!amountFromJsonNoThrow(saDstAmount, dstAmount.getJson())"); log << "Dst amount: " << saDstAmount; auto jvSrcCurrencies = Json::Value(Json::arrayValue); for (auto const& srcCurrency : srcCurrencies) { jvSrcCurrencies.append(srcCurrency.getJson()); } log << "Source currencies: " << jvSrcCurrencies; auto result = ripplePathFind(cache, src.pk, dest.pk, saDstAmount, ledger, jvSrcCurrencies, contextPaths, level); if(!result.first) throw std::runtime_error( "ripplePathFind find failed"); return result.second; }
UniValue ValueFromAmount(const Amount &amount) { int64_t amt = amount.GetSatoshis(); bool sign = amt < 0; int64_t n_abs = (sign ? -amt : amt); int64_t quotient = n_abs / COIN.GetSatoshis(); int64_t remainder = n_abs % COIN.GetSatoshis(); return UniValue(UniValue::VNUM, strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); }
Quality composed_quality (Quality const& lhs, Quality const& rhs) { Amount const lhs_rate (lhs.rate ()); assert (lhs_rate != zero); Amount const rhs_rate (rhs.rate ()); assert (rhs_rate != zero); Amount const rate (Amount::mulRound (lhs_rate, rhs_rate, true)); std::uint64_t const stored_exponent (rate.getExponent () + 100); std::uint64_t const stored_mantissa (rate.getMantissa ()); assert ((stored_exponent >= 0) && (stored_exponent <= 255)); return Quality ((stored_exponent << (64 - 8)) | stored_mantissa); }
const DocumentPtr Document::CreateTemplate() const { DocumentPtr doc(new Document()); doc->m_id = hb::EmptyId; doc->m_doc_date = this->m_doc_date; doc->m_doc_type_id = this->m_doc_type_id; if (m_amount_from.is_initialized()) { const Amount& this_amount = this->m_amount_from.get(); Amount amount; amount.SetAccount(this_amount.Account()); amount.SetCurrency(this_amount.Currency()); doc->SetAmountFrom(amount); } if (m_amount_to.is_initialized()) { const Amount& this_amount = this->m_amount_to.get(); Amount amount; amount.SetAccount(this_amount.Account()); amount.SetCurrency(this_amount.Currency()); doc->SetAmountTo(amount); } doc->m_note = ""; doc->m_shop = this->m_shop; return doc; }
void verifyBalance(Ledger::pointer ledger, TestAccount const& account, Amount const& amount) { auto sle = getLedgerEntryRippleState(ledger, account, amount.getIssuer(), amount.getCurrency()); if (!sle) throw std::runtime_error( "!sle"); STAmount amountReq; amountFromJsonNoThrow(amountReq, amount.getJson()); auto high = sle->getFieldAmount(sfHighLimit); auto balance = sle->getFieldAmount(sfBalance); if (high.getIssuer() == account.pk.getAccountID()) { balance.negate(); } if (balance != amountReq) throw std::runtime_error( "balance != amountReq"); }
uint64_t CTxOutCompressor::CompressAmount(Amount amt) { uint64_t n = amt.GetSatoshis(); if (n == 0) { return 0; } int e = 0; while (((n % 10) == 0) && e < 9) { n /= 10; e++; } if (e < 9) { int d = (n % 10); assert(d >= 1 && d <= 9); n /= 10; return 1 + (n * 9 + d - 1) * 10 + e; } else { return 1 + (n - 1) * 10 + 9; } }