Пример #1
0
MEP::MEP(const char *data, const uint16_t & dataLength,
		const char *originalData) throw (BrokenPacketReceivedError,
				UnknownSourceIDFound) :
		etherFrame_(originalData), rawData((struct MEP_HDR*) (data)), checkSumsVarified_(
				false) {

	events = new MEPFragment*[rawData->eventCount];
	if (getLength() != dataLength) {
		if (getLength() > dataLength) {
			throw BrokenPacketReceivedError(
					"Incomplete MEP! Received only "
							+ boost::lexical_cast<std::string>(dataLength)
							+ " of "
							+ boost::lexical_cast<std::string>(getLength())
							+ " bytes");
		} else {
			throw BrokenPacketReceivedError(
					"Received MEP longer than 'mep length' field! Received "
							+ boost::lexical_cast<std::string>(dataLength)
							+ " instead of "
							+ boost::lexical_cast<std::string>(getLength())
							+ " bytes");
		}
	}

	/*
	 * Try if the sourceID is correct
	 *
	 * TODO: Do we need to check the sourceID? This is quite expensive!
	 */
	if (!SourceIDManager::CheckL0SourceID(getSourceID())) {
		throw UnknownSourceIDFound(getSourceID());
	}
	initializeMEPFragments(data, dataLength);
}
Пример #2
0
// make sure the deleted Account hasn't issued credit
// make sure we aren't holding any credit
// make sure the we delete all the offers
// make sure the we delete all the trustlines
// move the XLM to the new account
bool
MergeOpFrame::doApply(LedgerDelta& delta, LedgerManager& ledgerManager)
{
    AccountFrame::pointer otherAccount;
    Database& db = ledgerManager.getDatabase();

    otherAccount = AccountFrame::loadAccount(mOperation.body.destination(), db);

    if (!otherAccount)
    {
        innerResult().code(ACCOUNT_MERGE_NO_ACCOUNT);
        return false;
    }

    if (TrustFrame::hasIssued(getSourceID(), db))
    {
        innerResult().code(ACCOUNT_MERGE_CREDIT_HELD);
        return false;
    }

    std::vector<TrustFrame::pointer> lines;
    TrustFrame::loadLines(getSourceID(), lines, db);
    for(auto &l : lines)
    {
        if(l->getBalance() > 0)
        {
            innerResult().code(ACCOUNT_MERGE_HAS_CREDIT);
            return false;
        }
    }

    // delete offers
    std::vector<OfferFrame::pointer> offers;
    OfferFrame::loadOffers(getSourceID(), offers, db);
    for (auto& offer : offers)
    {
        offer->storeDelete(delta, db);
    }

    // delete trust lines
    for (auto& l : lines)
    {
        l->storeDelete(delta, db);
    }

    otherAccount->getAccount().balance += mSourceAccount->getAccount().balance;
    otherAccount->storeChange(delta, db);
    mSourceAccount->storeDelete(delta, db);

    innerResult().code(ACCOUNT_MERGE_SUCCESS);
    return true;
}
Пример #3
0
bool
MergeOpFrame::doCheckValid()
{
    // makes sure not merging into self
    if (getSourceID() == mOperation.body.destination())
    {
        innerResult().code(ACCOUNT_MERGE_MALFORMED);
        return false;
    }
    return true;
}
Пример #4
0
NLPacketList::NLPacketList(PacketList&& other) : PacketList(std::move(other)) {
    // Update _packets
    for (auto& packet : _packets) {
        packet = NLPacket::fromBase(std::move(packet));
    }

    if (_packets.size() > 0) {
        auto nlPacket = static_cast<const NLPacket*>(_packets.front().get());
        _sourceID = nlPacket->getSourceID();
        _packetType = nlPacket->getType();
    }
}
Пример #5
0
bool
AllowTrustOpFrame::doCheckValid(Application& app)
{
    if (mAllowTrust.asset.type() == ASSET_TYPE_NATIVE)
    {
        app.getMetrics()
            .NewMeter({"op-allow-trust", "invalid", "malformed-non-alphanum"},
                      "operation")
            .Mark();
        innerResult().code(ALLOW_TRUST_MALFORMED);
        return false;
    }
    Asset ci;
    ci.type(mAllowTrust.asset.type());
    if (mAllowTrust.asset.type() == ASSET_TYPE_CREDIT_ALPHANUM4)
    {
        ci.alphaNum4().assetCode = mAllowTrust.asset.assetCode4();
        ci.alphaNum4().issuer = getSourceID();
    }
    else if (mAllowTrust.asset.type() == ASSET_TYPE_CREDIT_ALPHANUM12)
    {
        ci.alphaNum12().assetCode = mAllowTrust.asset.assetCode12();
        ci.alphaNum12().issuer = getSourceID();
    }

    if (!isAssetValid(ci))
    {
        app.getMetrics()
            .NewMeter({"op-allow-trust", "invalid", "malformed-invalid-asset"},
                      "operation")
            .Mark();
        innerResult().code(ALLOW_TRUST_MALFORMED);
        return false;
    }

    return true;
}
Пример #6
0
bool
MergeOpFrame::doCheckValid(Application& app, uint32_t ledgerVersion)
{
    // makes sure not merging into self
    if (getSourceID() == mOperation.body.destination())
    {
        app.getMetrics()
            .NewMeter({"op-merge", "invalid", "malformed-self-merge"},
                      "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_MALFORMED);
        return false;
    }
    return true;
}
bool
AllowTrustOpFrame::doCheckValid()
{
    if (mAllowTrust.currency.type() != CURRENCY_TYPE_ALPHANUM)
    {
        innerResult().code(ALLOW_TRUST_MALFORMED);
        return false;
    }
    Currency ci;
    ci.type(CURRENCY_TYPE_ALPHANUM);
    ci.alphaNum().currencyCode = mAllowTrust.currency.currencyCode();
    ci.alphaNum().issuer = getSourceID();

    if (!isCurrencyValid(ci))
    {
        innerResult().code(ALLOW_TRUST_MALFORMED);
        return false;
    }

    return true;
}
bool
AllowTrustOpFrame::doApply(LedgerDelta& delta, LedgerManager& ledgerManager)
{
    if (!(mSourceAccount->getAccount().flags & AUTH_REQUIRED_FLAG))
    { // this account doesn't require authorization to hold credit
        innerResult().code(ALLOW_TRUST_TRUST_NOT_REQUIRED);
        return false;
    }

    if (!(mSourceAccount->getAccount().flags & AUTH_REVOCABLE_FLAG) &&
        !mAllowTrust.authorize)
    {
        innerResult().code(ALLOW_TRUST_CANT_REVOKE);
        return false;
    }

    Currency ci;
    ci.type(CURRENCY_TYPE_ALPHANUM);
    ci.alphaNum().currencyCode = mAllowTrust.currency.currencyCode();
    ci.alphaNum().issuer = getSourceID();

    Database& db = ledgerManager.getDatabase();
    TrustFrame::pointer trustLine;
    trustLine = TrustFrame::loadTrustLine(mAllowTrust.trustor, ci, db);

    if (!trustLine)
    {
        innerResult().code(ALLOW_TRUST_NO_TRUST_LINE);
        return false;
    }

    innerResult().code(ALLOW_TRUST_SUCCESS);

    trustLine->setAuthorized(mAllowTrust.authorize);

    trustLine->storeChange(delta, db);

    return true;
}
Пример #9
0
	/**
	 * Starting from the SPECIE node, the function parses all the REGUL tags and reads the data from them.
	 * If not provided, attributes are defaulted - threshold to 1, label to Label::free
	 */
	static void parseRegulations(const rapidxml::xml_node<> * const specie_node, Model & model) {
		// Get ID of the regulated component
		string name;
		XMLHelper::getAttribute(name, specie_node, "name", true);
		const SpecieID t_ID = ModelTranslators::findID(model, name);

		// Cycle through REGUL TAGS
		for (auto regulation : XMLHelper::NodesRange(specie_node, "REGUL", true)) {
			string label;
			if (!XMLHelper::getAttribute(label, regulation, "label", false))
				label = Label::Free;
			SpecieID s_ID = getSourceID(regulation, t_ID, model);
			size_t threshold = getThreshold(regulation, t_ID, s_ID, model);

			// Add a new regulation to the specified target
			model.addRegulation(s_ID, t_ID, threshold, label);
		}

		// Sort regulators lexicographically
		rng::sort(model.species[t_ID].regulations, [](const Model::Regulation & A, const Model::Regulation & B) {
			return A.source < B.source;
		});
	}
BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask)
{
	BOOL handled = FALSE;

	if (!mDragItem)
	{
		// leave hover segment active during drag and drop
		mHoverSegment = NULL;
	}
	if(hasMouseCapture() )
	{
		if( mIsSelecting ) 
		{
			if (x != mLastSelectionX || y != mLastSelectionY)
			{
				mLastSelectionX = x;
				mLastSelectionY = y;
			}

			if( y > getTextRect().mTop )
			{
				mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 );
			}
			else
			if( y < getTextRect().mBottom )
			{
				mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 );
			}

			setCursorAtLocalPos( x, y, TRUE );
			mSelectionEnd = mCursorPos;
			
			updateScrollFromCursor();
			getWindow()->setCursor(UI_CURSOR_IBEAM);
		}
		else if( mDragItem )
		{
			S32 screen_x;
			S32 screen_y;
			localPointToScreen(x, y, &screen_x, &screen_y );
			if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
			{
				LLToolDragAndDrop::getInstance()->beginDrag(
					LLViewerAssetType::lookupDragAndDropType( mDragItem->getType() ),
					mDragItem->getUUID(),
					LLToolDragAndDrop::SOURCE_NOTECARD,
					getSourceID(), mObjectID);

				return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
			}
			getWindow()->setCursor(UI_CURSOR_HAND);
		}

		LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
		handled = TRUE;
	}

	if( !handled )
	{
		// Pass to children
		handled = LLView::childrenHandleHover(x, y, mask) != NULL;
	}

	if( handled )
	{
		// Delay cursor flashing
		resetKeystrokeTimer();
	}

	// Opaque
	if( !handled && mTakesNonScrollClicks)
	{
		// Check to see if we're over an HTML-style link
		if( !mSegments.empty() )
		{
			LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
			if( cur_segment )
			{
				if(cur_segment->getStyle()->isLink())
				{
					LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (over link, inactive)" << LL_ENDL;
					getWindow()->setCursor(UI_CURSOR_HAND);
					handled = TRUE;
				}
				else
				if(cur_segment->getStyle()->getIsEmbeddedItem())
				{
					LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (over embedded item, inactive)" << LL_ENDL;
					getWindow()->setCursor(UI_CURSOR_HAND);
					//getWindow()->setCursor(UI_CURSOR_ARROW);
					handled = TRUE;
				}
				mHoverSegment = cur_segment;
			}
		}

		if( !handled )
		{
			LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
			if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE)
			{
				getWindow()->setCursor(UI_CURSOR_IBEAM);
			}
			else
			{
				getWindow()->setCursor(UI_CURSOR_ARROW);
			}
			handled = TRUE;
		}
	}

	return handled;
}
bool
ChangeTrustOpFrame::doApply(medida::MetricsRegistry& metrics,
                            LedgerDelta& delta, LedgerManager& ledgerManager)
{
    Database& db = ledgerManager.getDatabase();

    auto tlI = TrustFrame::loadTrustLineIssuer(getSourceID(), mChangeTrust.line,
                                               db, delta);

    auto& trustLine = tlI.first;
    auto& issuer = tlI.second;

    if (trustLine)
    { // we are modifying an old trustline

        if (mChangeTrust.limit < trustLine->getBalance())
        { // Can't drop the limit below the balance you are holding with them
            metrics.NewMeter({"op-change-trust", "failure", "invalid-limit"},
                             "operation").Mark();
            innerResult().code(CHANGE_TRUST_INVALID_LIMIT);
            return false;
        }

        if (mChangeTrust.limit == 0)
        {
            // line gets deleted
            trustLine->storeDelete(delta, db);
            mSourceAccount->addNumEntries(-1, ledgerManager);
            mSourceAccount->storeChange(delta, db);
        }
        else
        {
            if (!issuer)
            {
                metrics.NewMeter({"op-change-trust", "failure", "no-issuer"},
                                 "operation").Mark();
                innerResult().code(CHANGE_TRUST_NO_ISSUER);
                return false;
            }
            trustLine->getTrustLine().limit = mChangeTrust.limit;
            trustLine->storeChange(delta, db);
        }
        metrics.NewMeter({"op-change-trust", "success", "apply"}, "operation")
            .Mark();
        innerResult().code(CHANGE_TRUST_SUCCESS);
        return true;
    }
    else
    { // new trust line
        if (mChangeTrust.limit == 0)
        {
            metrics.NewMeter({"op-change-trust", "failure", "invalid-limit"},
                             "operation").Mark();
            innerResult().code(CHANGE_TRUST_INVALID_LIMIT);
            return false;
        }
        if (!issuer)
        {
            metrics.NewMeter({"op-change-trust", "failure", "no-issuer"},
                             "operation").Mark();
            innerResult().code(CHANGE_TRUST_NO_ISSUER);
            return false;
        }
        trustLine = std::make_shared<TrustFrame>();
        auto& tl = trustLine->getTrustLine();
        tl.accountID = getSourceID();
        tl.asset = mChangeTrust.line;
        tl.limit = mChangeTrust.limit;
        tl.balance = 0;
        trustLine->setAuthorized(!issuer->isAuthRequired());

        if (!mSourceAccount->addNumEntries(1, ledgerManager))
        {
            metrics.NewMeter({"op-change-trust", "failure", "low-reserve"},
                             "operation").Mark();
            innerResult().code(CHANGE_TRUST_LOW_RESERVE);
            return false;
        }

        mSourceAccount->storeChange(delta, db);
        trustLine->storeAdd(delta, db);

        metrics.NewMeter({"op-change-trust", "success", "apply"}, "operation")
            .Mark();
        innerResult().code(CHANGE_TRUST_SUCCESS);
        return true;
    }
}
Пример #12
0
bool
SetOptionsOpFrame::doApply(AbstractLedgerTxn& ltx)
{
    auto header = ltx.loadHeader();
    auto sourceAccount = loadSourceAccount(ltx, header);
    auto& account = sourceAccount.current().data.account();
    if (mSetOptions.inflationDest)
    {
        AccountID inflationID = *mSetOptions.inflationDest;
        if (!(inflationID == getSourceID()))
        {
            if (!stellar::loadAccountWithoutRecord(ltx, inflationID))
            {
                innerResult().code(SET_OPTIONS_INVALID_INFLATION);
                return false;
            }
        }
        account.inflationDest.activate() = inflationID;
    }

    if (mSetOptions.clearFlags)
    {
        if ((*mSetOptions.clearFlags & allAccountAuthFlags) &&
            isImmutableAuth(sourceAccount))
        {
            innerResult().code(SET_OPTIONS_CANT_CHANGE);
            return false;
        }
        account.flags = account.flags & ~*mSetOptions.clearFlags;
    }

    if (mSetOptions.setFlags)
    {
        if ((*mSetOptions.setFlags & allAccountAuthFlags) &&
            isImmutableAuth(sourceAccount))
        {
            innerResult().code(SET_OPTIONS_CANT_CHANGE);
            return false;
        }
        account.flags = account.flags | *mSetOptions.setFlags;
    }

    if (mSetOptions.homeDomain)
    {
        account.homeDomain = *mSetOptions.homeDomain;
    }

    if (mSetOptions.masterWeight)
    {
        account.thresholds[THRESHOLD_MASTER_WEIGHT] =
            *mSetOptions.masterWeight & UINT8_MAX;
    }

    if (mSetOptions.lowThreshold)
    {
        account.thresholds[THRESHOLD_LOW] =
            *mSetOptions.lowThreshold & UINT8_MAX;
    }

    if (mSetOptions.medThreshold)
    {
        account.thresholds[THRESHOLD_MED] =
            *mSetOptions.medThreshold & UINT8_MAX;
    }

    if (mSetOptions.highThreshold)
    {
        account.thresholds[THRESHOLD_HIGH] =
            *mSetOptions.highThreshold & UINT8_MAX;
    }

    if (mSetOptions.signer)
    {
        auto& signers = account.signers;
        if (mSetOptions.signer->weight)
        { // add or change signer
            bool found = false;
            for (auto& oldSigner : signers)
            {
                if (oldSigner.key == mSetOptions.signer->key)
                {
                    oldSigner.weight = mSetOptions.signer->weight;
                    found = true;
                }
            }
            if (!found)
            {
                if (signers.size() == signers.max_size())
                {
                    innerResult().code(SET_OPTIONS_TOO_MANY_SIGNERS);
                    return false;
                }
                switch (addNumEntries(header, sourceAccount, 1))
                {
                case AddSubentryResult::SUCCESS:
                    break;
                case AddSubentryResult::LOW_RESERVE:
                    innerResult().code(SET_OPTIONS_LOW_RESERVE);
                    return false;
                case AddSubentryResult::TOO_MANY_SUBENTRIES:
                    mResult.code(opTOO_MANY_SUBENTRIES);
                    return false;
                default:
                    throw std::runtime_error(
                        "Unexpected result from addNumEntries");
                }

                signers.push_back(*mSetOptions.signer);
            }
        }
        else
        { // delete signer
            auto it = signers.begin();
            while (it != signers.end())
            {
                Signer& oldSigner = *it;
                if (oldSigner.key == mSetOptions.signer->key)
                {
                    it = signers.erase(it);
                    addNumEntries(header, sourceAccount, -1);
                }
                else
                {
                    it++;
                }
            }
        }
        normalizeSigners(sourceAccount);
    }

    innerResult().code(SET_OPTIONS_SUCCESS);
    return true;
}
Пример #13
0
bool
SetOptionsOpFrame::doCheckValid(uint32_t ledgerVersion)
{
    if (mSetOptions.setFlags)
    {
        if (*mSetOptions.setFlags & ~allAccountFlags)
        {
            innerResult().code(SET_OPTIONS_UNKNOWN_FLAG);
            return false;
        }
    }

    if (mSetOptions.clearFlags)
    {
        if (*mSetOptions.clearFlags & ~allAccountFlags)
        {
            innerResult().code(SET_OPTIONS_UNKNOWN_FLAG);
            return false;
        }
    }

    if (mSetOptions.setFlags && mSetOptions.clearFlags)
    {
        if ((*mSetOptions.setFlags & *mSetOptions.clearFlags) != 0)
        {
            innerResult().code(SET_OPTIONS_BAD_FLAGS);
            return false;
        }
    }

    if (mSetOptions.masterWeight)
    {
        if (*mSetOptions.masterWeight > UINT8_MAX)
        {
            innerResult().code(SET_OPTIONS_THRESHOLD_OUT_OF_RANGE);
            return false;
        }
    }

    if (mSetOptions.lowThreshold)
    {
        if (*mSetOptions.lowThreshold > UINT8_MAX)
        {
            innerResult().code(SET_OPTIONS_THRESHOLD_OUT_OF_RANGE);
            return false;
        }
    }

    if (mSetOptions.medThreshold)
    {
        if (*mSetOptions.medThreshold > UINT8_MAX)
        {
            innerResult().code(SET_OPTIONS_THRESHOLD_OUT_OF_RANGE);
            return false;
        }
    }

    if (mSetOptions.highThreshold)
    {
        if (*mSetOptions.highThreshold > UINT8_MAX)
        {
            innerResult().code(SET_OPTIONS_THRESHOLD_OUT_OF_RANGE);
            return false;
        }
    }

    if (mSetOptions.signer)
    {
        auto isSelf = mSetOptions.signer->key ==
                      KeyUtils::convertKey<SignerKey>(getSourceID());
        auto isPublicKey =
            KeyUtils::canConvert<PublicKey>(mSetOptions.signer->key);
        if (isSelf || (!isPublicKey && ledgerVersion < 3))
        {
            innerResult().code(SET_OPTIONS_BAD_SIGNER);
            return false;
        }
        if (mSetOptions.signer->weight > UINT8_MAX && ledgerVersion > 9)
        {
            innerResult().code(SET_OPTIONS_BAD_SIGNER);
            return false;
        }
    }

    if (mSetOptions.homeDomain)
    {
        if (!isString32Valid(*mSetOptions.homeDomain))
        {
            innerResult().code(SET_OPTIONS_INVALID_HOME_DOMAIN);
            return false;
        }
    }

    return true;
}
Пример #14
0
// make sure the deleted Account hasn't issued credit
// make sure we aren't holding any credit
// make sure the we delete all the offers
// make sure the we delete all the trustlines
// move the XLM to the new account
bool
MergeOpFrame::doApply(Application& app, AbstractLedgerState& ls)
{
    auto header = ls.loadHeader();

    auto otherAccount = stellar::loadAccount(ls, mOperation.body.destination());
    if (!otherAccount)
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "no-account"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_NO_ACCOUNT);
        return false;
    }

    int64_t sourceBalance = 0;
    if (header.current().ledgerVersion > 4 &&
        header.current().ledgerVersion < 8)
    {
        // in versions < 8, merge account could be called with a stale account
        LedgerKey key(ACCOUNT);
        key.account().accountID = getSourceID();
        auto thisAccount = ls.loadWithoutRecord(key);
        if (!thisAccount)
        {
            app.getMetrics()
                .NewMeter({"op-merge", "failure", "no-account"}, "operation")
                .Mark();
            innerResult().code(ACCOUNT_MERGE_NO_ACCOUNT);
            return false;
        }

        if (header.current().ledgerVersion > 5)
        {
            sourceBalance = thisAccount.current().data.account().balance;
        }
    }

    auto sourceAccountEntry = loadSourceAccount(ls, header);
    auto const& sourceAccount = sourceAccountEntry.current().data.account();
    // Only set sourceBalance here if it wasn't set in the previous block
    if (header.current().ledgerVersion <= 5 ||
        header.current().ledgerVersion >= 8)
    {
        sourceBalance = sourceAccount.balance;
    }

    if (isImmutableAuth(sourceAccountEntry))
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "static-auth"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_IMMUTABLE_SET);
        return false;
    }

    if (sourceAccount.numSubEntries != sourceAccount.signers.size())
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "has-sub-entries"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_HAS_SUB_ENTRIES);
        return false;
    }

    if (header.current().ledgerVersion >= 10)
    {
        SequenceNumber maxSeq = getStartingSequenceNumber(header);

        // don't allow the account to be merged if recreating it would cause it
        // to jump backwards
        if (sourceAccount.seqNum >= maxSeq)
        {
            app.getMetrics()
                .NewMeter({"op-merge", "failure", "too-far"}, "operation")
                .Mark();
            innerResult().code(ACCOUNT_MERGE_SEQNUM_TOO_FAR);
            return false;
        }
    }

    // "success" path starts
    if (!addBalance(header, otherAccount, sourceBalance))
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "dest-full"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_DEST_FULL);
        return false;
    }

    sourceAccountEntry.erase();

    app.getMetrics()
        .NewMeter({"op-merge", "success", "apply"}, "operation")
        .Mark();
    innerResult().code(ACCOUNT_MERGE_SUCCESS);
    innerResult().sourceAccountBalance() = sourceBalance;
    return true;
}
Пример #15
0
bool
AllowTrustOpFrame::doApply(Application& app, LedgerDelta& delta,
                           LedgerManager& ledgerManager)
{
    if (ledgerManager.getCurrentLedgerVersion() > 2)
    {
        if (mAllowTrust.trustor == getSourceID())
        { // since version 3 it is not
            // allowed to use ALLOW_TRUST on
            // self
            app.getMetrics()
                .NewMeter({"op-allow-trust", "failure", "trust-self"},
                          "operation")
                .Mark();
            innerResult().code(ALLOW_TRUST_SELF_NOT_ALLOWED);
            return false;
        }
    }

    if (!(mSourceAccount->getAccount().flags & AUTH_REQUIRED_FLAG))
    { // this account doesn't require authorization to
        // hold credit
        app.getMetrics()
            .NewMeter({"op-allow-trust", "failure", "not-required"},
                      "operation")
            .Mark();
        innerResult().code(ALLOW_TRUST_TRUST_NOT_REQUIRED);
        return false;
    }

    if (!(mSourceAccount->getAccount().flags & AUTH_REVOCABLE_FLAG) &&
        !mAllowTrust.authorize)
    {
        app.getMetrics()
            .NewMeter({"op-allow-trust", "failure", "cant-revoke"}, "operation")
            .Mark();
        innerResult().code(ALLOW_TRUST_CANT_REVOKE);
        return false;
    }

    Asset ci;
    ci.type(mAllowTrust.asset.type());
    if (mAllowTrust.asset.type() == ASSET_TYPE_CREDIT_ALPHANUM4)
    {
        ci.alphaNum4().assetCode = mAllowTrust.asset.assetCode4();
        ci.alphaNum4().issuer = getSourceID();
    }
    else if (mAllowTrust.asset.type() == ASSET_TYPE_CREDIT_ALPHANUM12)
    {
        ci.alphaNum12().assetCode = mAllowTrust.asset.assetCode12();
        ci.alphaNum12().issuer = getSourceID();
    }

    Database& db = ledgerManager.getDatabase();
    TrustFrame::pointer trustLine;
    trustLine = TrustFrame::loadTrustLine(mAllowTrust.trustor, ci, db, &delta);

    if (!trustLine)
    {
        app.getMetrics()
            .NewMeter({"op-allow-trust", "failure", "no-trust-line"},
                      "operation")
            .Mark();
        innerResult().code(ALLOW_TRUST_NO_TRUST_LINE);
        return false;
    }

    app.getMetrics()
        .NewMeter({"op-allow-trust", "success", "apply"}, "operation")
        .Mark();
    innerResult().code(ALLOW_TRUST_SUCCESS);

    trustLine->setAuthorized(mAllowTrust.authorize);

    trustLine->storeChange(delta, db);

    return true;
}