mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-04 18:55:49 +00:00
fix: uritoken destination & amount preflight check (#188)
* fix: uritoken destination & amount * Update URIToken.cpp * add lsfBurnable flag * make uritoken patch a fix amendment * clang-format
This commit is contained in:
@@ -45,7 +45,6 @@ include(RippledSanity)
|
|||||||
include(RippledVersion)
|
include(RippledVersion)
|
||||||
include(RippledSettings)
|
include(RippledSettings)
|
||||||
include(RippledNIH)
|
include(RippledNIH)
|
||||||
|
|
||||||
# this check has to remain in the top-level cmake
|
# this check has to remain in the top-level cmake
|
||||||
# because of the early return statement
|
# because of the early return statement
|
||||||
if (packages_only)
|
if (packages_only)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
|
|||||||
// issuer is also a strong TSH if the burnable flag is set
|
// issuer is also a strong TSH if the burnable flag is set
|
||||||
auto const issuer = ut->getAccountID(sfIssuer);
|
auto const issuer = ut->getAccountID(sfIssuer);
|
||||||
if (issuer != owner)
|
if (issuer != owner)
|
||||||
ADD_TSH(issuer, ut->getFlags() & tfBurnable);
|
ADD_TSH(issuer, ut->getFlags() & lsfBurnable);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
|
|||||||
|
|
||||||
// issuer is a strong TSH if the burnable flag is set
|
// issuer is a strong TSH if the burnable flag is set
|
||||||
if (issuer != owner)
|
if (issuer != owner)
|
||||||
ADD_TSH(issuer, ut->getFlags() & tfBurnable);
|
ADD_TSH(issuer, ut->getFlags() & lsfBurnable);
|
||||||
|
|
||||||
// destination is a strong tsh
|
// destination is a strong tsh
|
||||||
if (tx.isFieldPresent(sfDestination))
|
if (tx.isFieldPresent(sfDestination))
|
||||||
|
|||||||
@@ -78,6 +78,17 @@ URIToken::preflight(PreflightContext const& ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix amendment to return temMALFORMED if sfDestination field is present
|
||||||
|
// and sfAmount field is not present
|
||||||
|
if (ctx.rules.enabled(fixURITokenV1))
|
||||||
|
{
|
||||||
|
if (ctx.tx.isFieldPresent(sfDestination) &&
|
||||||
|
!ctx.tx.isFieldPresent(sfAmount))
|
||||||
|
{
|
||||||
|
return temMALFORMED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the validation for the URI field is also the same regardless of the txn
|
// the validation for the URI field is also the same regardless of the txn
|
||||||
// type
|
// type
|
||||||
if (ctx.tx.isFieldPresent(sfURI))
|
if (ctx.tx.isFieldPresent(sfURI))
|
||||||
@@ -231,7 +242,7 @@ URIToken::preclaim(PreclaimContext const& ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ttURITOKEN_BURN: {
|
case ttURITOKEN_BURN: {
|
||||||
if (leFlags == tfBurnable && acc == *issuer)
|
if (leFlags == lsfBurnable && acc == *issuer)
|
||||||
{
|
{
|
||||||
// pass, the issuer can burn the URIToken if they minted it with
|
// pass, the issuer can burn the URIToken if they minted it with
|
||||||
// a burn flag
|
// a burn flag
|
||||||
@@ -805,9 +816,9 @@ URIToken::doApply()
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
sleU->getAccountID(sfIssuer) == account_ &&
|
sleU->getAccountID(sfIssuer) == account_ &&
|
||||||
(sleU->getFlags() & tfBurnable))
|
(sleU->getFlags() & lsfBurnable))
|
||||||
{
|
{
|
||||||
// pass, issuer may burn if the tfBurnable flag was set during
|
// pass, issuer may burn if the lsfBurnable flag was set during
|
||||||
// minting
|
// minting
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace detail {
|
|||||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
||||||
// the actual number of amendments. A LogicError on startup will verify this.
|
// the actual number of amendments. A LogicError on startup will verify this.
|
||||||
static constexpr std::size_t numFeatures = 65;
|
static constexpr std::size_t numFeatures = 66;
|
||||||
|
|
||||||
/** Amendments that this server supports and the default voting behavior.
|
/** Amendments that this server supports and the default voting behavior.
|
||||||
Whether they are enabled depends on the Rules defined in the validated
|
Whether they are enabled depends on the Rules defined in the validated
|
||||||
@@ -353,6 +353,7 @@ extern uint256 const fixNFTokenRemint;
|
|||||||
extern uint256 const featureImport;
|
extern uint256 const featureImport;
|
||||||
extern uint256 const featureXahauGenesis;
|
extern uint256 const featureXahauGenesis;
|
||||||
extern uint256 const featureHooksUpdate1;
|
extern uint256 const featureHooksUpdate1;
|
||||||
|
extern uint256 const fixURITokenV1;
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|
||||||
|
|||||||
@@ -310,6 +310,9 @@ enum LedgerSpecificFlags {
|
|||||||
|
|
||||||
// ltNFTOKEN_OFFER
|
// ltNFTOKEN_OFFER
|
||||||
lsfSellNFToken = 0x00000001,
|
lsfSellNFToken = 0x00000001,
|
||||||
|
|
||||||
|
// ltURI_TOKEN
|
||||||
|
lsfBurnable = 0x00000001, // True, issuer can burn the token
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ REGISTER_FEATURE(URIToken, Supported::yes, VoteBehavior::De
|
|||||||
REGISTER_FEATURE(Import, Supported::yes, VoteBehavior::DefaultYes);
|
REGISTER_FEATURE(Import, Supported::yes, VoteBehavior::DefaultYes);
|
||||||
REGISTER_FEATURE(XahauGenesis, Supported::yes, VoteBehavior::DefaultYes);
|
REGISTER_FEATURE(XahauGenesis, Supported::yes, VoteBehavior::DefaultYes);
|
||||||
REGISTER_FEATURE(HooksUpdate1, Supported::yes, VoteBehavior::DefaultYes);
|
REGISTER_FEATURE(HooksUpdate1, Supported::yes, VoteBehavior::DefaultYes);
|
||||||
|
REGISTER_FIX (fixURITokenV1, Supported::yes, VoteBehavior::DefaultNo);
|
||||||
|
|
||||||
|
|
||||||
// The following amendments are obsolete, but must remain supported
|
// The following amendments are obsolete, but must remain supported
|
||||||
|
|||||||
@@ -260,6 +260,34 @@ struct URIToken_test : public beast::unit_test::suite
|
|||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
// fixURITokenV1
|
||||||
|
{
|
||||||
|
for (bool const withFixURITokenV1 : {true, false})
|
||||||
|
{
|
||||||
|
auto const amend =
|
||||||
|
withFixURITokenV1 ? features : features - fixURITokenV1;
|
||||||
|
|
||||||
|
auto const txResult =
|
||||||
|
withFixURITokenV1 ? ter(temMALFORMED) : ter(tefINTERNAL);
|
||||||
|
|
||||||
|
Env env{*this, amend};
|
||||||
|
auto const alice = Account("alice");
|
||||||
|
auto const bob = Account("bob");
|
||||||
|
env.fund(XRP(1000), alice, bob);
|
||||||
|
env.close();
|
||||||
|
|
||||||
|
std::string const uri(2, '?');
|
||||||
|
auto const tid = tokenid(alice, uri);
|
||||||
|
std::string const hexid{strHex(tid)};
|
||||||
|
|
||||||
|
// temMALFORMED - cannot include sfDestination without sfAmount
|
||||||
|
Json::Value destTx = mint(alice, uri);
|
||||||
|
destTx[jss::Destination] = bob.human();
|
||||||
|
env(destTx, txResult);
|
||||||
|
env.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setup env
|
// setup env
|
||||||
Env env{*this, features};
|
Env env{*this, features};
|
||||||
auto const alice = Account("alice");
|
auto const alice = Account("alice");
|
||||||
|
|||||||
@@ -1705,7 +1705,7 @@ public:
|
|||||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||||
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
|
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
|
||||||
BEAST_EXPECT(jrr[jss::node][sfURI.jsonName] == strHex(uri));
|
BEAST_EXPECT(jrr[jss::node][sfURI.jsonName] == strHex(uri));
|
||||||
BEAST_EXPECT(jrr[jss::node][sfFlags.jsonName] == 1);
|
BEAST_EXPECT(jrr[jss::node][sfFlags.jsonName] == lsfBurnable);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Request an index that is not a uritoken.
|
// Request an index that is not a uritoken.
|
||||||
|
|||||||
Reference in New Issue
Block a user