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.
Fix payment for unauthorized holder
  • Loading branch information
gregtatcam committed Aug 13, 2024
1 parent 749a80a commit 4b2e103
Show file tree
Hide file tree
Showing 24 changed files with 452 additions and 108 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
15 changes: 7 additions & 8 deletions src/libxrpl/protocol/STObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +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())
{
throwFieldErr(e.sField().fieldName, "doesn't support MPT");
}
}
v.emplace_back(std::move(*iter));
v_.erase(iter);
}
Expand Down Expand Up @@ -638,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 4b2e103

Please sign in to comment.