Skip to content

A trust line with only lsf*Auth flags set is removed from the ledger [rippled version 1.12.0-rc4] #4698

@scottschurr

Description

@scottschurr

Issue Description

A trust line is removed from the ledger unexpectedly.

Steps to Reproduce

The following unit test member function reproduces the problem.

    void
    testTrustLineWithOnlySetfAuthIsRemoved()
    {
        testcase("Trust line with only lsf*Auth");
        using namespace jtx;

        Env env{*this};

        // auth1 and auth2 are both issuers that require authorization.  They
        // will create a (required) trust line so they can cross offers between
        // themselves.
        Account const auth1("auth1");
        Account const auth2("auth2");
        auto const USD1 = auth1["USD"];
        auto const USD2 = auth2["USD"];

        env.fund(XRP(100000), auth1, auth2);
        env.close();
        env.require(owners(auth1, 0), owners(auth2, 0));

        // Trust lines to auth issuers must be authorized.
        env(fset(auth1, asfRequireAuth));
        env(fset(auth2, asfRequireAuth));
        env.close();

        // Since auth1 and auth2 have the asfRequireAuth flag set in their
        // accounts, they must explicitly give permission to holders of
        // their currencies.  This call creates a trust line with one of the
        // lsf*Auth flags set.
        env(trust(auth1, USD2(0), tfSetfAuth));
        env.close();
        // After creating the trust line we find this ledger entry as expected.
        BEAST_EXPECT(env.le(
            keylet::line(auth1.id(), auth2.id(), USD1.currency)));
        env.require(owners(auth1, 1), owners(auth2, 0));

        // Now auth2 reciprocates by attempting to set the other lsf*Auth
        // flag in the trust line.  Surprisingly, the trust line is removed
        // instead.
        env(trust(auth2, USD1(0), tfSetfAuth));
        env.close();
        // There's no good reason why the immediately preceeding TrustSet
        // should cause the previously inserted trust line to be removed
        // from the ledger.  But that's what happens.  So the following
        // tests fail.
        BEAST_EXPECT(env.le(
            keylet::line(auth1.id(), auth2.id(), USD1.currency)));
        env.require(owners(auth1, 1), owners(auth2, 1));
    }

The workaround is easy. Setting a non-zero trust limit changes the behaviors. Setting non-zero trust limits on both sides of the trust line results in expected behavior.

Given that there's an easy work around, use non-zero trust limits, this is not a high priority bug.

Environment

macOS Monterey 12.5.1
Apple clang version 13.1.6 (clang-1316.0.21.2.5)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions