bool CharCreationManager::IsLastNameAvailable(const char* lastname, AccountID requestingAcct) { if(!lastname || strlen(lastname) < 1) return true; // blank last names are allowed. // Check to see if name already exists in character database. csString query; csString escape; db->Escape(escape, lastname); query.Format("SELECT account_id FROM characters WHERE lastname='%s'", escape.GetData()); Result result(db->Select(query)); if(result.IsValid()) { if(result.Count() == 0) return true; // nobody owns it yet, it's available if(requestingAcct.IsValid()) { for(unsigned int i = 0; i < result.Count(); i++) { if(AccountID(result[i].GetInt("account_id")) == requestingAcct) return true; // another character on the same account; available } } } return false; // already in use by someone else }
BanManager::BanManager() { Result result(db->Select("SELECT * FROM bans")); if (!result.IsValid()) return; time_t now = time(0); for (unsigned int i=0; i<result.Count(); i++) { AccountID account = AccountID(result[i].GetUInt32("account")); time_t end = result[i].GetUInt32("end"); if (now > end) // Time served { db->Command("DELETE FROM bans WHERE account='%u'", account.Unbox()); continue; } BanEntry* newentry = new BanEntry; newentry->account = account; newentry->end = end; newentry->start = result[i].GetUInt32("start"); newentry->ipRange = result[i]["ip_range"]; newentry->reason = result[i]["reason"]; newentry->banIP = result[i].GetUInt32("ban_ip") != 0; // If account ban, add to list if (newentry->account.IsValid()) banList_IDHash.Put(newentry->account,newentry); // If IP range ban, add to list if ( newentry->ipRange.Length() && newentry->banIP /*(!end || now < newentry->start + IP_RANGE_BAN_TIME)*/ ) banList_IPRList.Push(newentry); } }
Amounts cross (Amounts offer, Quality quality) { if (reject (quality)) return Amounts (offer.in.zeroed (), offer.out.zeroed ()); // we need to emulate "unfunded offers" behavior if (get_funds (AccountID (0x4702), offer.out) == beast::zero) return Amounts (offer.in.zeroed (), offer.out.zeroed ()); if (done ()) return Amounts (offer.in.zeroed (), offer.out.zeroed ()); auto result = do_cross (offer, quality, AccountID (0x4702)); funds_ -= result.order.in; return result.order; }
std::pair<Amounts, Amounts> cross (Amounts offer1, Quality quality1, Amounts offer2, Quality quality2) { /* check if composed quality should be rejected */ Quality const quality (composed_quality ( quality1, quality2)); if (reject (quality)) return std::make_pair( Amounts { offer1.in.zeroed (), offer1.out.zeroed () }, Amounts { offer2.in.zeroed (), offer2.out.zeroed () }); if (done ()) return std::make_pair( Amounts { offer1.in.zeroed (), offer1.out.zeroed () }, Amounts { offer2.in.zeroed (), offer2.out.zeroed () }); auto result = do_cross ( offer1, quality1, AccountID (0x4703), offer2, quality2, AccountID (0x4704)); return std::make_pair (result.first.order, result.second.order); }
TestTaker ( CrossType cross_type, Amounts const& amount, Quality const& quality, STAmount const& funds, std::uint32_t flags, Rate const& rate_in, Rate const& rate_out) : BasicTaker ( cross_type, AccountID(0x4701), amount, quality, flags, rate_in, rate_out) , funds_ (funds) { }
void FeeVoteImpl::doVoting (Ledger::ref lastClosedLedger, std::shared_ptr<SHAMap> const& initialPosition) { // LCL must be flag ledger assert ((lastClosedLedger->getLedgerSeq () % 256) == 0); detail::VotableInteger<std::uint64_t> baseFeeVote ( lastClosedLedger->getBaseFee (), target_.reference_fee); detail::VotableInteger<std::uint32_t> baseReserveVote ( lastClosedLedger->getReserve (0), target_.account_reserve); detail::VotableInteger<std::uint32_t> incReserveVote ( lastClosedLedger->getReserveInc (), target_.owner_reserve); // get validations for ledger before flag ValidationSet const set = getApp().getValidations ().getValidations ( lastClosedLedger->getParentHash ()); for (auto const& e : set) { STValidation const& val = *e.second; if (val.isTrusted ()) { if (val.isFieldPresent (sfBaseFee)) { baseFeeVote.addVote (val.getFieldU64 (sfBaseFee)); } else { baseFeeVote.noVote (); } if (val.isFieldPresent (sfReserveBase)) { baseReserveVote.addVote (val.getFieldU32 (sfReserveBase)); } else { baseReserveVote.noVote (); } if (val.isFieldPresent (sfReserveIncrement)) { incReserveVote.addVote (val.getFieldU32 (sfReserveIncrement)); } else { incReserveVote.noVote (); } } } // choose our positions std::uint64_t const baseFee = baseFeeVote.getVotes (); std::uint32_t const baseReserve = baseReserveVote.getVotes (); std::uint32_t const incReserve = incReserveVote.getVotes (); // add transactions to our position if ((baseFee != lastClosedLedger->getBaseFee ()) || (baseReserve != lastClosedLedger->getReserve (0)) || (incReserve != lastClosedLedger->getReserveInc ())) { if (journal_.warning) journal_.warning << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; STTx trans (ttFEE); trans.setFieldAccount (sfAccount, AccountID ()); trans.setFieldU64 (sfBaseFee, baseFee); trans.setFieldU32 (sfReferenceFeeUnits, 10); trans.setFieldU32 (sfReserveBase, baseReserve); trans.setFieldU32 (sfReserveIncrement, incReserve); uint256 txID = trans.getTransactionID (); if (journal_.warning) journal_.warning << "Vote: " << txID; Serializer s; trans.add (s); auto tItem = std::make_shared<SHAMapItem> (txID, s.peekData ()); if (!initialPosition->addGiveItem (tItem, true, false)) { if (journal_.warning) journal_.warning << "Ledger already had fee change"; } } }
void FeeVoteImpl::doVoting( std::shared_ptr<ReadView const> const& lastClosedLedger, ValidationSet const& set, std::shared_ptr<SHAMap> const& initialPosition) { // LCL must be flag ledger assert ((lastClosedLedger->info().seq % 256) == 0); detail::VotableInteger<std::uint64_t> baseFeeVote ( lastClosedLedger->fees().base, target_.reference_fee); detail::VotableInteger<std::uint32_t> baseReserveVote ( lastClosedLedger->fees().accountReserve(0).drops(), target_.account_reserve); detail::VotableInteger<std::uint32_t> incReserveVote ( lastClosedLedger->fees().increment, target_.owner_reserve); for (auto const& e : set) { STValidation const& val = *e.second; if (val.isTrusted ()) { if (val.isFieldPresent (sfBaseFee)) { baseFeeVote.addVote (val.getFieldU64 (sfBaseFee)); } else { baseFeeVote.noVote (); } if (val.isFieldPresent (sfReserveBase)) { baseReserveVote.addVote (val.getFieldU32 (sfReserveBase)); } else { baseReserveVote.noVote (); } if (val.isFieldPresent (sfReserveIncrement)) { incReserveVote.addVote (val.getFieldU32 (sfReserveIncrement)); } else { incReserveVote.noVote (); } } } // choose our positions std::uint64_t const baseFee = baseFeeVote.getVotes (); std::uint32_t const baseReserve = baseReserveVote.getVotes (); std::uint32_t const incReserve = incReserveVote.getVotes (); std::uint32_t const feeUnits = target_.reference_fee_units; auto const seq = lastClosedLedger->info().seq + 1; // add transactions to our position if ((baseFee != lastClosedLedger->fees().base) || (baseReserve != lastClosedLedger->fees().accountReserve(0)) || (incReserve != lastClosedLedger->fees().increment)) { if (journal_.warning) journal_.warning << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; STTx feeTx (ttFEE, [seq,baseFee,baseReserve,incReserve,feeUnits](auto& obj) { obj[sfAccount] = AccountID(); obj[sfLedgerSequence] = seq; obj[sfBaseFee] = baseFee; obj[sfReserveBase] = baseReserve; obj[sfReserveIncrement] = incReserve; obj[sfReferenceFeeUnits] = feeUnits; }); uint256 txID = feeTx.getTransactionID (); if (journal_.warning) journal_.warning << "Vote: " << txID; Serializer s; feeTx.add (s); auto tItem = std::make_shared<SHAMapItem> (txID, s.peekData ()); if (!initialPosition->addGiveItem (tItem, true, false)) { if (journal_.warning) journal_.warning << "Ledger already had fee change"; } } }
// Set this object to be an expanded path from spSourcePath - take the implied // nodes and makes them explicit. It also sanitizes the path. // // There are only two types of nodes: account nodes and order books nodes. // // You can infer some nodes automatically. If you're paying me bitstamp USD, // then there must be an intermediate bitstamp node. // // If you have accounts A and B, and they're delivery currency issued by C, then // there must be a node with account C in the middle. // // If you're paying USD and getting bitcoins, there has to be an order book in // between. // // terStatus = tesSUCCESS, temBAD_PATH, terNO_LINE, terNO_ACCOUNT, terNO_AUTH, // or temBAD_PATH_LOOP TER PathState::expandPath ( STPath const& spSourcePath, AccountID const& uReceiverID, AccountID const& uSenderID) { uQuality = 1; // Mark path as active. Currency const& uMaxCurrencyID = saInReq.getCurrency (); AccountID const& uMaxIssuerID = saInReq.getIssuer (); Currency const& currencyOutID = saOutReq.getCurrency (); AccountID const& issuerOutID = saOutReq.getIssuer (); AccountID const& uSenderIssuerID = isXRP(uMaxCurrencyID) ? xrpAccount() : uSenderID; // Sender is always issuer for non-XRP. JLOG (j_.trace) << "expandPath> " << spSourcePath.getJson (0); terStatus = tesSUCCESS; // XRP with issuer is malformed. if ((isXRP (uMaxCurrencyID) && !isXRP (uMaxIssuerID)) || (isXRP (currencyOutID) && !isXRP (issuerOutID))) { JLOG (j_.debug) << "expandPath> issuer with XRP"; terStatus = temBAD_PATH; } // Push sending node. // For non-XRP, issuer is always sending account. // - Trying to expand, not-compact. // - Every issuer will be traversed through. if (terStatus == tesSUCCESS) { terStatus = pushNode ( !isXRP(uMaxCurrencyID) ? STPathElement::typeAccount | STPathElement::typeCurrency | STPathElement::typeIssuer : STPathElement::typeAccount | STPathElement::typeCurrency, uSenderID, uMaxCurrencyID, // Max specifies the currency. uSenderIssuerID); } JLOG (j_.debug) << "expandPath: pushed:" << " account=" << uSenderID << " currency=" << uMaxCurrencyID << " issuer=" << uSenderIssuerID; // Issuer was not same as sender. if (tesSUCCESS == terStatus && uMaxIssuerID != uSenderIssuerID) { // May have an implied account node. // - If it was XRP, then issuers would have matched. // Figure out next node properties for implied node. const auto uNxtCurrencyID = spSourcePath.size () ? Currency(spSourcePath.front ().getCurrency ()) // Use next node. : currencyOutID; // Use send. // TODO(tom): complexify this next logic further in case someone // understands it. const auto nextAccountID = spSourcePath.size () ? AccountID(spSourcePath. front ().getAccountID ()) : !isXRP(currencyOutID) ? (issuerOutID == uReceiverID) ? AccountID(uReceiverID) : AccountID(issuerOutID) // Use implied node. : xrpAccount(); JLOG (j_.debug) << "expandPath: implied check:" << " uMaxIssuerID=" << uMaxIssuerID << " uSenderIssuerID=" << uSenderIssuerID << " uNxtCurrencyID=" << uNxtCurrencyID << " nextAccountID=" << nextAccountID; // Can't just use push implied, because it can't compensate for next // account. if (!uNxtCurrencyID // Next is XRP, offer next. Must go through issuer. || uMaxCurrencyID != uNxtCurrencyID // Next is different currency, offer next... || uMaxIssuerID != nextAccountID) // Next is not implied issuer { JLOG (j_.debug) << "expandPath: sender implied:" << " account=" << uMaxIssuerID << " currency=" << uMaxCurrencyID << " issuer=" << uMaxIssuerID; // Add account implied by SendMax. terStatus = pushNode ( !isXRP(uMaxCurrencyID) ? STPathElement::typeAccount | STPathElement::typeCurrency | STPathElement::typeIssuer : STPathElement::typeAccount | STPathElement::typeCurrency, uMaxIssuerID, uMaxCurrencyID, uMaxIssuerID); } } for (auto & speElement: spSourcePath) { if (terStatus == tesSUCCESS) { JLOG (j_.trace) << "expandPath: element in path"; terStatus = pushNode ( speElement.getNodeType (), speElement.getAccountID (), speElement.getCurrency (), speElement.getIssuerID ()); } } if (terStatus == tesSUCCESS && !isXRP(currencyOutID) // Next is not XRP && issuerOutID != uReceiverID) // Out issuer is not receiver { assert (!nodes_.empty ()); auto const& backNode = nodes_.back (); if (backNode.issue_.currency != currencyOutID // Previous will be offer || backNode.account_ != issuerOutID) // Need implied issuer { // Add implied account. JLOG (j_.debug) << "expandPath: receiver implied:" << " account=" << issuerOutID << " currency=" << currencyOutID << " issuer=" << issuerOutID; terStatus = pushNode ( !isXRP(currencyOutID) ? STPathElement::typeAccount | STPathElement::typeCurrency | STPathElement::typeIssuer : STPathElement::typeAccount | STPathElement::typeCurrency, issuerOutID, currencyOutID, issuerOutID); } } if (terStatus == tesSUCCESS) { // Create receiver node. // Last node is always an account. terStatus = pushNode ( !isXRP(currencyOutID) ? STPathElement::typeAccount | STPathElement::typeCurrency | STPathElement::typeIssuer : STPathElement::typeAccount | STPathElement::typeCurrency, uReceiverID, // Receive to output currencyOutID, // Desired currency uReceiverID); } if (terStatus == tesSUCCESS) { // Look for first mention of source in nodes and detect loops. // Note: The output is not allowed to be a source. unsigned int index = 0; for (auto& node: nodes_) { AccountIssue accountIssue (node.account_, node.issue_); if (!umForward.insert ({accountIssue, index++}).second) { // Failed to insert. Have a loop. JLOG (j_.debug) << "expandPath: loop detected: " << getJson (); terStatus = temBAD_PATH_LOOP; break; } } } JLOG (j_.debug) << "expandPath:" << " in=" << uMaxCurrencyID << "/" << uMaxIssuerID << " out=" << currencyOutID << "/" << issuerOutID << ": " << getJson (); return terStatus; }
// Create a raw, non-integral amount from mantissa and exponent STAmount static raw (std::uint64_t mantissa, int exponent) { return STAmount ({Currency(3), AccountID(3)}, mantissa, exponent); }
Issue const& eur () const { static Issue const issue ( Currency (0x4555520000000000), AccountID (0x4985602)); return issue; }
Issue const& usd () const { static Issue const issue ( Currency (0x5553440000000000), AccountID (0x4985601)); return issue; }