bool STAccount::getValueH160 (uint160& v) const { if (!isValueH160 ()) return false; memcpy (v.begin (), & (peekValue ().front ()), (160 / 8)); return true; }
void OrderBookDB::addOrderBook(const uint160& ci, const uint160& co, const uint160& ii, const uint160& io) { bool toXRP = co.isZero(); ScopedLockType sl (mLock, __FILE__, __LINE__); if (toXRP) { // We don't want to search through all the to-XRP or from-XRP order books! BOOST_FOREACH(OrderBook::ref ob, mSourceMap[currencyIssuer_ct(ci, ii)]) { if ((ob->getCurrencyOut() == co) && (ob->getIssuerOut() == io)) return; } } else {
const std::string RemoteMinerClient::ReverseAddressHex(const uint160 address) const { std::string rval(""); std::string addresshex=address.GetHex(); for(std::string::size_type i=0; i<addresshex.size(); i+=2) { if(i+1<addresshex.size()) { rval=addresshex.substr(i,2)+rval; } else { rval=addresshex.substr(i,1)+rval; } } return rval; }
void RippleAddress::setAccountID(const uint160& hash160) { SetData(VER_ACCOUNT_ID, hash160.begin(), 20); }
void STAccount::setValueH160(const uint160& v) { peekValue().clear(); peekValue().insert(peekValue().end(), v.begin(), v.end()); assert(peekValue().size() == (160/8)); }
STAccount::STAccount(SField::ref n, const uint160& v) : STVariableLength(n) { peekValue().insert(peekValue().end(), v.begin(), v.end()); }
TER PaymentTransactor::doApply () { // Ripple if source or destination is non-native or if there are paths. std::uint32_t const uTxFlags = mTxn.getFlags (); //bool const bPartialPayment = is_bit_set(uTxFlags, tfPartialPayment); bool const bLimitQuality = is_bit_set (uTxFlags, tfLimitQuality); bool const bNoRippleDirect = is_bit_set (uTxFlags, tfNoRippleDirect); bool const bPaths = mTxn.isFieldPresent (sfPaths); bool const bMax = mTxn.isFieldPresent (sfSendMax); uint160 const uDstAccountID = mTxn.getFieldAccount160 (sfDestination); STAmount const saDstAmount = mTxn.getFieldAmount (sfAmount); STAmount const saMaxAmount = bMax ? mTxn.getFieldAmount (sfSendMax) : saDstAmount.isNative () ? saDstAmount : STAmount (saDstAmount.getCurrency (), mTxnAccountID, saDstAmount.getMantissa (), saDstAmount.getExponent (), saDstAmount < zero); uint160 const uSrcCurrency = saMaxAmount.getCurrency (); uint160 const uDstCurrency = saDstAmount.getCurrency (); bool const bSTRDirect = uSrcCurrency.isZero () && uDstCurrency.isZero (); m_journal.trace << "saMaxAmount=" << saMaxAmount.getFullText () << " saDstAmount=" << saDstAmount.getFullText (); if (!saDstAmount.isLegalNet () || !saMaxAmount.isLegalNet ()) return temBAD_AMOUNT; if (uTxFlags & tfPaymentMask) { m_journal.trace << "Malformed transaction: Invalid flags set."; return temINVALID_FLAG; } else if (!uDstAccountID) { m_journal.trace << "Malformed transaction: Payment destination account not specified."; return temDST_NEEDED; } else if (bMax && saMaxAmount <= zero) { m_journal.trace << "Malformed transaction: bad max amount: " << saMaxAmount.getFullText (); return temBAD_AMOUNT; } else if (saDstAmount <= zero) { m_journal.trace << "Malformed transaction: bad dst amount: " << saDstAmount.getFullText (); return temBAD_AMOUNT; } else if (CURRENCY_BAD == uSrcCurrency || CURRENCY_BAD == uDstCurrency) { m_journal.trace << "Malformed transaction: Bad currency."; return temBAD_CURRENCY; } else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths) { m_journal.trace << "Malformed transaction: Redundant transaction:" << " src=" << to_string (mTxnAccountID) << " dst=" << to_string (uDstAccountID) << " src_cur=" << to_string (uSrcCurrency) << " dst_cur=" << to_string (uDstCurrency); return temREDUNDANT; } else if (bMax && saMaxAmount == saDstAmount && saMaxAmount.getCurrency () == saDstAmount.getCurrency ()) { m_journal.trace << "Malformed transaction: Redundant SendMax."; return temREDUNDANT_SEND_MAX; } else if (bSTRDirect && bMax) { m_journal.trace << "Malformed transaction: SendMax specified for STR to STR."; return temBAD_SEND_STR_MAX; } else if (bSTRDirect && bPaths) { m_journal.trace << "Malformed transaction: Paths specified for STR to STR."; return temBAD_SEND_STR_PATHS; } else if (bSTRDirect && bLimitQuality) { m_journal.trace << "Malformed transaction: Limit quality specified for STR to STR."; return temBAD_SEND_STR_LIMIT; } else if (bSTRDirect && bNoRippleDirect) { m_journal.trace << "Malformed transaction: No ripple direct specified for STR to STR."; return temBAD_SEND_STR_NO_DIRECT; } SLE::pointer sleDst (mEngine->entryCache ( ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID))); if (!sleDst) { // Destination account does not exist. if (!saDstAmount.isNative ()) { m_journal.trace << "Delay transaction: Destination account does not exist."; // Another transaction could create the account and then this transaction would succeed. return tecNO_DST; } // Note: Reserve is not scaled by load. else if (saDstAmount.getNValue () < mEngine->getLedger ()->getReserve (0)) { m_journal.trace << "Delay transaction: Destination account does not exist. " << "Insufficient payment to create account."; // Another transaction could create the account and then this // transaction would succeed. return tecNO_DST_INSUF_STR; } // Create the account. sleDst = mEngine->entryCreate ( ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)); sleDst->setFieldAccount (sfAccount, uDstAccountID); sleDst->setFieldU32 (sfSequence, 1); } else if ((sleDst->getFlags () & lsfRequireDestTag) && !mTxn.isFieldPresent (sfDestinationTag)) { m_journal.trace << "Malformed transaction: DestinationTag required."; return tefDST_TAG_NEEDED; } else { mEngine->entryModify (sleDst); } TER terResult; // XXX Should bMax be sufficient to imply ripple? bool const bRipple = bPaths || bMax || !saDstAmount.isNative (); if (bRipple) { // Ripple payment STPathSet spsPaths = mTxn.getFieldPathSet (sfPaths); std::vector<PathState::pointer> vpsExpanded; STAmount saMaxAmountAct; STAmount saDstAmountAct; try { bool const openLedger = is_bit_set (mParams, tapOPEN_LEDGER); bool tooManyPaths = false; if (spsPaths.size() > MAX_NUM_PATHS) tooManyPaths = true; else { for (auto const& path : spsPaths) { if (path.size() > MAX_PATH_SIZE) { tooManyPaths = true; break; } } } terResult = openLedger && tooManyPaths ? telBAD_PATH_COUNT // Too many paths for proposed ledger. : RippleCalc::rippleCalc( mEngine->view(), saMaxAmountAct, saDstAmountAct, vpsExpanded, saMaxAmount, saDstAmount, uDstAccountID, mTxnAccountID, spsPaths, false, bLimitQuality, bNoRippleDirect, // Always compute for finalizing ledger. false, // Not standalone, delete unfundeds. is_bit_set(mParams, tapOPEN_LEDGER)); if (isTerRetry(terResult)) terResult = tecPATH_DRY; if ((tesSUCCESS == terResult) && (saDstAmountAct != saDstAmount)) mEngine->view().setDeliveredAmount(saDstAmountAct); } catch (std::exception const& e) { m_journal.trace << "Caught throw: " << e.what (); terResult = tefEXCEPTION; } } else { // Direct STR payment. std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount)); std::uint64_t const uReserve (mEngine->getLedger ()->getReserve (uOwnerCount)); // Make sure have enough reserve to send. Allow final spend to use reserve for fee. if (mPriorBalance < saDstAmount + std::max(uReserve, mTxn.getTransactionFee ().getNValue ())) { // Vote no. However, transaction might succeed, if applied in a different order. m_journal.trace << "Delay transaction: Insufficient funds: " << " " << mPriorBalance.getText () << " / " << (saDstAmount + uReserve).getText () << " (" << uReserve << ")"; terResult = tecUNFUNDED_PAYMENT; } else { mTxnAccount->setFieldAmount (sfBalance, mSourceBalance - saDstAmount); sleDst->setFieldAmount (sfBalance, sleDst->getFieldAmount (sfBalance) + saDstAmount); terResult = tesSUCCESS; } } std::string strToken; std::string strHuman; if (transResultInfo (terResult, strToken, strHuman)) { m_journal.trace << strToken << ": " << strHuman; } else { assert (false); } return terResult; }
TER WalletAddTransactor::doApply () { std::uint32_t const uTxFlags = mTxn.getFlags (); if (uTxFlags & tfUniversalMask) { m_journal.trace << "Malformed transaction: Invalid flags set."; return temINVALID_FLAG; } Blob const vucPubKey = mTxn.getFieldVL (sfPublicKey); Blob const vucSignature = mTxn.getFieldVL (sfSignature); uint160 const uAuthKeyID (mTxn.getFieldAccount160 (sfRegularKey)); RippleAddress const naMasterPubKey ( RippleAddress::createAccountPublic (vucPubKey)); uint160 const uDstAccountID (naMasterPubKey.getAccountID ()); // FIXME: This should be moved to the transaction's signature check logic and cached if (!naMasterPubKey.verifySignature( Serializer::getSHA512Half (uAuthKeyID.begin (), uAuthKeyID.size ()), vucSignature)) { m_journal.trace << "Unauthorized: bad signature "; return tefBAD_ADD_AUTH; } SLE::pointer sleDst (mEngine->entryCache ( ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID))); if (sleDst) { m_journal.trace << "account already created"; return tefCREATED; } // Direct STR payment. STAmount saDstAmount = mTxn.getFieldAmount (sfAmount); STAmount saPaid = mTxn.getTransactionFee (); STAmount const saSrcBalance = mTxnAccount->getFieldAmount (sfBalance); std::uint32_t const uOwnerCount = mTxnAccount->getFieldU32 (sfOwnerCount); std::uint64_t const uReserve = mEngine->getLedger ()->getReserve (uOwnerCount); // Make sure have enough reserve to send. Allow final spend to use reserve // for fee. // Note: Reserve is not scaled by fee. if (saSrcBalance + saPaid < saDstAmount + uReserve) { // Vote no. However, transaction might succeed, if applied in a // different order. m_journal.trace << "Delay transaction: Insufficient funds: %s / %s (%d)" << saSrcBalance.getText () << " / " << (saDstAmount + uReserve).getText () << " with reserve = " << uReserve; return tecUNFUNDED_ADD; } // Deduct initial balance from source account. mTxnAccount->setFieldAmount (sfBalance, saSrcBalance - saDstAmount); // Create the account. sleDst = mEngine->entryCreate (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)); sleDst->setFieldAccount (sfAccount, uDstAccountID); sleDst->setFieldU32 (sfSequence, 1); sleDst->setFieldAmount (sfBalance, saDstAmount); sleDst->setFieldAccount (sfRegularKey, uAuthKeyID); return tesSUCCESS; }
std::size_t hash_value (const uint160& u) { std::size_t seed = HashMaps::getInstance ().getNonce <size_t> (); return u.hash_combine (seed); }