diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj
index 7832b45b5..174450b5a 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj
+++ b/Builds/VisualStudio2015/RippleD.vcxproj
@@ -1713,6 +1713,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters
index 22ddc810d..55bb6b7b0 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters
@@ -2454,6 +2454,9 @@
ripple\app\tests
+
+ ripple\app\tests
+
ripple\app\tests
diff --git a/src/ripple/app/tests/SetAuth_test.cpp b/src/ripple/app/tests/SetAuth_test.cpp
new file mode 100644
index 000000000..4352e6906
--- /dev/null
+++ b/src/ripple/app/tests/SetAuth_test.cpp
@@ -0,0 +1,85 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include
+#include
+#include
+
+namespace ripple {
+namespace test {
+
+struct SetAuth_test : public beast::unit_test::suite
+{
+ // Set just the tfSetfAuth flag on a trust line
+ // If the trust line does not exist, then it should
+ // be created under the new rules.
+ static
+ Json::Value
+ auth (jtx::Account const& account,
+ jtx::Account const& dest,
+ std::string const& currency)
+ {
+ using namespace jtx;
+ Json::Value jv;
+ jv[jss::Account] = account.human();
+ jv[jss::LimitAmount] = STAmount(
+ { to_currency(currency), dest }).getJson(0);
+ jv[jss::TransactionType] = "TrustSet";
+ jv[jss::Flags] = tfSetfAuth;
+ return jv;
+ }
+
+ void testAuth()
+ {
+ using namespace jtx;
+ auto const gw = Account("gw");
+ auto const USD = gw["USD"];
+ {
+ Env env(*this);
+ env.disable_testing();
+ env.fund(XRP(100000), "alice", gw);
+ env(fset(gw, asfRequireAuth));
+ env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT));
+ }
+ {
+ Env env(*this);
+ env.fund(XRP(100000), "alice", "bob", gw);
+ env(fset(gw, asfRequireAuth));
+ env(auth(gw, "alice", "USD"));
+ expect(env.le(
+ keylet::line(Account("alice").id(),
+ gw.id(), USD.currency)));
+ env(trust("alice", USD(1000)));
+ env(trust("bob", USD(1000)));
+ env(pay(gw, "alice", USD(100)));
+ env(pay(gw, "bob", USD(100)), ter(tecPATH_DRY)); // Should be terNO_AUTH
+ env(pay("alice", "bob", USD(50)), ter(tecPATH_DRY)); // Should be terNO_AUTH
+ }
+ }
+
+ void run() override
+ {
+ testAuth();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(SetAuth,test,ripple);
+
+} // test
+} // ripple
diff --git a/src/ripple/app/tx/impl/SetTrust.cpp b/src/ripple/app/tx/impl/SetTrust.cpp
index b67619052..1d123eee2 100644
--- a/src/ripple/app/tx/impl/SetTrust.cpp
+++ b/src/ripple/app/tx/impl/SetTrust.cpp
@@ -18,6 +18,7 @@
//==============================================================================
#include
+#include
#include
#include
#include
@@ -397,9 +398,12 @@ SetTrust::doApply ()
}
}
// Line does not exist.
- else if (!saLimitAmount // Setting default limit.
- && (!bQualityIn || !uQualityIn) // Not setting quality in or setting default quality in.
- && (!bQualityOut || !uQualityOut)) // Not setting quality out or setting default quality out.
+ else if (! saLimitAmount && // Setting default limit.
+ (! bQualityIn || ! uQualityIn) && // Not setting quality in or setting default quality in.
+ (! bQualityOut || ! uQualityOut) && // Not setting quality out or setting default quality out.
+ (! ((view().flags() & tapENABLE_TESTING) ||
+ view().rules().enabled(featureTrustSetAuth,
+ ctx_.config.features)) || ! bSetAuth))
{
j_.trace <<
"Redundant: Setting non-existent ripple line to defaults.";
diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h
index 2eea444b0..7fbcd4fb4 100644
--- a/src/ripple/protocol/Feature.h
+++ b/src/ripple/protocol/Feature.h
@@ -36,6 +36,7 @@ feature (const char* name);
extern uint256 const featureMultiSign;
extern uint256 const featureSusPay;
+extern uint256 const featureTrustSetAuth;
} // ripple
diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp
index d37e0431f..49bc4d96c 100644
--- a/src/ripple/protocol/impl/Feature.cpp
+++ b/src/ripple/protocol/impl/Feature.cpp
@@ -47,5 +47,6 @@ feature (const char* name)
uint256 const featureMultiSign = feature("MultiSign");
uint256 const featureSusPay = feature("SusPay");
+uint256 const featureTrustSetAuth = feature("TrustSetAuth");
} // ripple
diff --git a/src/ripple/unity/app_tests.cpp b/src/ripple/unity/app_tests.cpp
index 8c110a2ba..de5f8d960 100644
--- a/src/ripple/unity/app_tests.cpp
+++ b/src/ripple/unity/app_tests.cpp
@@ -29,3 +29,4 @@
#include
#include
#include
+#include