Skip to content

Commit

Permalink
Add invalid MPT amount check in STTx::passesLocalChecks()
Browse files Browse the repository at this point in the history
to provide one single check for all tx.
Update unit-tests.
  • Loading branch information
gregtatcam committed Aug 13, 2024
1 parent f5081e8 commit 189362e
Show file tree
Hide file tree
Showing 23 changed files with 407 additions and 196 deletions.
3 changes: 3 additions & 0 deletions include/xrpl/protocol/MPTIssue.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ isXRP(uint192 const&)
return false;
}

Json::Value
to_json(MPTIssue const& issue);

} // namespace ripple

#endif // RIPPLE_PROTOCOL_MPTISSUE_H_INCLUDED
8 changes: 3 additions & 5 deletions include/xrpl/protocol/SOTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ class SOElement

public:
SOElement(SField const& fieldName, SOEStyle style)
: sField_(fieldName)
, style_(style)
, supportMpt_(SOETxMPTAmount::soeMPTNone)
: sField_(fieldName), style_(style), supportMpt_(soeMPTNone)
{
init(fieldName);
}
Expand Down Expand Up @@ -101,10 +99,10 @@ class SOElement
return style_;
}

bool
SOETxMPTAmount
supportMPT() const
{
return supportMpt_ == soeMPTSupported;
return supportMpt_;
}
};

Expand Down
3 changes: 0 additions & 3 deletions include/xrpl/protocol/STEitherAmount.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ operator==(STEitherAmount const& lhs, STEitherAmount const& rhs)
},
lhs.getValue(),
rhs.getValue());
if (lhs.isIssue() == rhs.isIssue())
return lhs.getValue() == rhs.getValue();
return false;
}

inline bool
Expand Down
2 changes: 2 additions & 0 deletions include/xrpl/protocol/STObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ class STObject : public STBase, public CountedObject<STObject>
Blob
getFieldVL(SField const& field) const;
STEitherAmount const&
getFieldEitherAmount(SField const& field) const;
STEitherAmount const&
getFieldAmount(SField const& field) const;
STAmount const&
getFieldAmount(TypedFieldAmount<SFieldMPT::No> const& field) const;
Expand Down
6 changes: 3 additions & 3 deletions include/xrpl/protocol/XChainAttestations.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ struct AttestationClaim : AttestationBase
message(
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STEitherAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
Expand Down Expand Up @@ -226,8 +226,8 @@ struct AttestationCreateAccount : AttestationBase
message(
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount const& rewardAmount,
STEitherAmount const& sendingAmount,
STEitherAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
Expand Down
9 changes: 9 additions & 0 deletions src/libxrpl/protocol/MPTIssue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/jss.h>

namespace ripple {

Expand Down Expand Up @@ -67,4 +68,12 @@ getMPT(uint192 const& id)
return std::make_pair(sequence, account);
}

Json::Value
to_json(MPTIssue const& issue)
{
Json::Value jv;
jv[jss::mpt_issuance_id] = to_string(issue.getMptID());
return jv;
}

} // namespace ripple
12 changes: 3 additions & 9 deletions src/libxrpl/protocol/STEitherAmount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
//==============================================================================

#include <xrpl/basics/Log.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/STEitherAmount.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/protocol/jss.h>
Expand Down Expand Up @@ -246,14 +244,10 @@ amountFromJson(SField const& name, Json::Value const& v)
value = v[jss::value];
if (v.isMember(jss::mpt_issuance_id))
{
std::optional<Rules> const& rules = getCurrentTransactionRules();
if (!rules || (rules && rules->enabled(featureMPTokensV1)))
{
isMPT = true;
currencyOrMPTID = v[jss::mpt_issuance_id];
}
isMPT = true;
currencyOrMPTID = v[jss::mpt_issuance_id];
}
if (!isMPT)
else
{
currencyOrMPTID = v[jss::currency];
issuer = v[jss::issuer];
Expand Down
19 changes: 7 additions & 12 deletions src/libxrpl/protocol/STObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,6 @@ STObject::applyTemplate(const SOTemplate& type)
e.sField().fieldName,
"may not be explicitly set to default.");
}
if (iter->get().getSType() == STI_AMOUNT && !e.supportMPT())
{
if (auto const v = dynamic_cast<STEitherAmount*>(&iter->get());
v && v->isMPT())
{
std::optional<Rules> const& rules =
getCurrentTransactionRules();
if (!rules || rules->enabled(featureMPTokensV1))
throwFieldErr(
e.sField().fieldName, "doesn't support MPT");
}
}
v.emplace_back(std::move(*iter));
v_.erase(iter);
}
Expand Down Expand Up @@ -642,6 +630,13 @@ STObject::getFieldVL(SField const& field) const
return Blob(b.data(), b.data() + b.size());
}

STEitherAmount const&
STObject::getFieldEitherAmount(SField const& field) const
{
static STEitherAmount const empty{};
return getFieldByConstRef<STEitherAmount>(field, empty);
}

STEitherAmount const&
STObject::getFieldAmount(SField const& field) const
{
Expand Down
32 changes: 32 additions & 0 deletions src/libxrpl/protocol/STTx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,31 @@ isAccountFieldOkay(STObject const& st)
return true;
}

static bool
invalidMPTAmountInTx(STObject const& tx)
{
auto const txType = tx[~sfTransactionType];
if (!txType)
return false;
if (auto const* item = TxFormats::getInstance().findByType(safe_cast<TxType>(*txType)))
{
for (auto const& e : item->getSOTemplate())
{
if (tx.isFieldPresent(e.sField()) && e.supportMPT() != soeMPTNone)
{
if (auto const& field = tx.peekAtField(e.sField());
field.getSType() == STI_AMOUNT &&
static_cast<STEitherAmount const&>(field).isMPT())
{
if (e.supportMPT() == soeMPTNotSupported)
return true;
}
}
}
}
return false;
}

bool
passesLocalChecks(STObject const& st, std::string& reason)
{
Expand All @@ -560,6 +585,13 @@ passesLocalChecks(STObject const& st, std::string& reason)
reason = "Cannot submit pseudo transactions.";
return false;
}

if (invalidMPTAmountInTx(st))
{
reason = "Amount can not be MPT.";
return false;
}

return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/libxrpl/protocol/XChainAttestations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ std::vector<std::uint8_t>
AttestationClaim::message(
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STEitherAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
Expand All @@ -225,7 +225,7 @@ AttestationClaim::message(
STObject o{sfGeneric};
// Serialize in SField order to make python serializers easier to write
o[sfXChainClaimID] = claimID;
o[sfAmount] = STEitherAmount{sendingAmount};
o[sfAmount] = sendingAmount;
if (dst)
o[sfDestination] = *dst;
o[sfOtherChainSource] = sendingAccount;
Expand Down Expand Up @@ -361,8 +361,8 @@ std::vector<std::uint8_t>
AttestationCreateAccount::message(
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount const& rewardAmount,
STEitherAmount const& sendingAmount,
STEitherAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
Expand Down
Loading

0 comments on commit 189362e

Please sign in to comment.