Skip to content

Commit

Permalink
Resolve conflicts with mpt-v1
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Aug 26, 2024
2 parents 496f600 + 9578002 commit 8298f81
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 55 deletions.
14 changes: 7 additions & 7 deletions include/xrpl/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ JSS(AuthAccount); // in: AMM Auction Slot
JSS(AuthAccounts); // in: AMM Auction Slot
JSS(BaseAsset); // in: Oracle
JSS(Bridge); // ledger type.
JSS(MPToken); // ledger type.
JSS(MPTokenIssuance); // ledger type.
JSS(MPTokenIssuanceCreate); // transaction type.
JSS(MPTokenIssuanceDestroy); // transaction type.
JSS(MPTokenAuthorize); // transaction type.
JSS(MPTokenIssuanceSet); // transaction type.
JSS(MPTokenIssuanceID); // in: MPTokenIssuanceDestroy, MPTokenAuthorize
JSS(Check); // ledger type.
JSS(CheckCancel); // transaction type.
JSS(CheckCash); // transaction type.
Expand Down Expand Up @@ -103,6 +96,13 @@ JSS(LedgerHashes); // ledger type.
JSS(LimitAmount); // field.
JSS(BidMax); // in: AMM Bid
JSS(BidMin); // in: AMM Bid
JSS(MPToken); // ledger type.
JSS(MPTokenIssuance); // ledger type.
JSS(MPTokenIssuanceCreate); // transaction type.
JSS(MPTokenIssuanceDestroy); // transaction type.
JSS(MPTokenAuthorize); // transaction type.
JSS(MPTokenIssuanceSet); // transaction type.
JSS(MPTokenIssuanceID); // in: MPTokenIssuanceDestroy, MPTokenAuthorize
JSS(NetworkID); // field.
JSS(NFTokenBurn); // transaction type.
JSS(NFTokenMint); // transaction type.
Expand Down
1 change: 1 addition & 0 deletions src/libxrpl/protocol/TER.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ transResults()
MAKE_ERROR(temINVALID_COUNT, "Malformed: Count field outside valid range."),
MAKE_ERROR(temSEQ_AND_TICKET, "Transaction contains a TicketSequence and a non-zero Sequence."),
MAKE_ERROR(temBAD_NFTOKEN_TRANSFER_FEE, "Malformed: The NFToken transfer fee must be between 1 and 5000, inclusive."),
MAKE_ERROR(temBAD_MPTOKEN_TRANSFER_FEE, "Malformed: The MPToken transfer fee must be between 1 and 5000, inclusive."),
MAKE_ERROR(temXCHAIN_EQUAL_DOOR_ACCOUNTS, "Malformed: Bridge must have unique door accounts."),
MAKE_ERROR(temXCHAIN_BAD_PROOF, "Malformed: Bad cross-chain claim proof."),
MAKE_ERROR(temXCHAIN_BRIDGE_BAD_ISSUES, "Malformed: Bad bridge issues."),
Expand Down
10 changes: 9 additions & 1 deletion src/test/app/MPToken_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class MPToken_test : public beast::unit_test::suite
.metadata = "test",
.err = temMALFORMED});

// tries to set a txfee while not enabling transfer
// tries to set a txfee greater than max
mptAlice.create(
{.maxAmt = 100,
.assetScale = 0,
Expand All @@ -68,6 +68,14 @@ class MPToken_test : public beast::unit_test::suite
.flags = tfMPTCanTransfer,
.err = temBAD_MPTOKEN_TRANSFER_FEE});

// tries to set a txfee while not enabling transfer
mptAlice.create(
{.maxAmt = 100,
.assetScale = 0,
.transferFee = maxTransferFee,
.metadata = "test",
.err = temMALFORMED});

// empty metadata returns error
mptAlice.create(
{.maxAmt = 100,
Expand Down
74 changes: 47 additions & 27 deletions src/xrpld/app/tx/detail/MPTokenAuthorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,40 +126,41 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx)
}

TER
MPTokenAuthorize::doApply()
MPTokenAuthorize::authorize(
ApplyView& view,
beast::Journal journal,
MPTAuthorizeArgs const& args)
{
auto const mptIssuanceID = ctx_.tx[sfMPTokenIssuanceID];
auto const sleAcct = view().peek(keylet::account(account_));
auto const sleAcct = view.peek(keylet::account(args.account));
if (!sleAcct)
return tecINTERNAL;

auto const holderID = ctx_.tx[~sfMPTokenHolder];

// If the account that submitted the tx is a holder
// Note: `account_` is holder's account
// `holderID` is NOT used
if (!holderID)
if (!args.holderID)
{
// When a holder wants to unauthorize/delete a MPT, the ledger must
// - delete mptokenKey from owner directory
// - delete the MPToken
if (ctx_.tx.getFlags() & tfMPTUnauthorize)
if (args.flags & tfMPTUnauthorize)
{
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account_);
auto const sleMpt = view().peek(mptokenKey);
auto const mptokenKey =
keylet::mptoken(args.mptIssuanceID, args.account);
auto const sleMpt = view.peek(mptokenKey);
if (!sleMpt)
return tecINTERNAL;

if (!view().dirRemove(
keylet::ownerDir(account_),
if (!view.dirRemove(
keylet::ownerDir(args.account),
(*sleMpt)[sfOwnerNode],
sleMpt->key(),
false))
return tecINTERNAL;

adjustOwnerCount(view(), sleAcct, -1, j_);
adjustOwnerCount(view, sleAcct, -1, journal);

view().erase(sleMpt);
view.erase(sleMpt);
return tesSUCCESS;
}

Expand All @@ -169,43 +170,48 @@ MPTokenAuthorize::doApply()
std::uint32_t const uOwnerCount = sleAcct->getFieldU32(sfOwnerCount);
XRPAmount const reserveCreate(
(uOwnerCount < 2) ? XRPAmount(beast::zero)
: view().fees().accountReserve(uOwnerCount + 1));
: view.fees().accountReserve(uOwnerCount + 1));

if (mPriorBalance < reserveCreate)
if (args.priorBalance < reserveCreate)
return tecINSUFFICIENT_RESERVE;

auto const mptokenKey = keylet::mptoken(mptIssuanceID, account_);
auto const mptokenKey =
keylet::mptoken(args.mptIssuanceID, args.account);

auto const ownerNode = view().dirInsert(
keylet::ownerDir(account_), mptokenKey, describeOwnerDir(account_));
auto const ownerNode = view.dirInsert(
keylet::ownerDir(args.account),
mptokenKey,
describeOwnerDir(args.account));

if (!ownerNode)
return tecDIR_FULL;

auto mptoken = std::make_shared<SLE>(mptokenKey);
(*mptoken)[sfAccount] = account_;
(*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID;
(*mptoken)[sfAccount] = args.account;
(*mptoken)[sfMPTokenIssuanceID] = args.mptIssuanceID;
(*mptoken)[sfFlags] = 0;
(*mptoken)[sfOwnerNode] = *ownerNode;
view().insert(mptoken);
view.insert(mptoken);

// Update owner count.
adjustOwnerCount(view(), sleAcct, 1, j_);
adjustOwnerCount(view, sleAcct, 1, journal);

return tesSUCCESS;
}

auto const sleMptIssuance = view().read(keylet::mptIssuance(mptIssuanceID));
auto const sleMptIssuance =
view.read(keylet::mptIssuance(args.mptIssuanceID));
if (!sleMptIssuance)
return tecINTERNAL;

// If the account that submitted this tx is the issuer of the MPT
// Note: `account_` is issuer's account
// `holderID` is holder's account
if (account_ != (*sleMptIssuance)[sfIssuer])
if (args.account != (*sleMptIssuance)[sfIssuer])
return tecINTERNAL;

auto const sleMpt = view().peek(keylet::mptoken(mptIssuanceID, *holderID));
auto const sleMpt =
view.peek(keylet::mptoken(args.mptIssuanceID, *args.holderID));
if (!sleMpt)
return tecINTERNAL;

Expand All @@ -214,7 +220,7 @@ MPTokenAuthorize::doApply()

// Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on
// their MPToken
if (ctx_.tx.getFlags() & tfMPTUnauthorize)
if (args.flags & tfMPTUnauthorize)
flagsOut &= ~lsfMPTAuthorized;
// Issuer wants to authorize a holder, set lsfMPTAuthorized on their
// MPToken
Expand All @@ -224,8 +230,22 @@ MPTokenAuthorize::doApply()
if (flagsIn != flagsOut)
sleMpt->setFieldU32(sfFlags, flagsOut);

view().update(sleMpt);
view.update(sleMpt);
return tesSUCCESS;
}

TER
MPTokenAuthorize::doApply()
{
auto const& tx = ctx_.tx;
return authorize(
ctx_.view(),
ctx_.journal,
{.priorBalance = mPriorBalance,
.mptIssuanceID = tx[sfMPTokenIssuanceID],
.account = account_,
.flags = tx.getFlags(),
.holderID = tx[~sfMPTokenHolder]});
}

} // namespace ripple
15 changes: 15 additions & 0 deletions src/xrpld/app/tx/detail/MPTokenAuthorize.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@

namespace ripple {

struct MPTAuthorizeArgs
{
XRPAmount const& priorBalance;
uint192 const& mptIssuanceID;
AccountID const& account;
std::uint32_t flags;
std::optional<AccountID> holderID;
};

class MPTokenAuthorize : public Transactor
{
public:
Expand All @@ -39,6 +48,12 @@ class MPTokenAuthorize : public Transactor
static TER
preclaim(PreclaimContext const& ctx);

static TER
authorize(
ApplyView& view,
beast::Journal journal,
MPTAuthorizeArgs const& args);

TER
doApply() override;
};
Expand Down
61 changes: 41 additions & 20 deletions src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,54 +68,75 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx)
}

TER
MPTokenIssuanceCreate::doApply()
MPTokenIssuanceCreate::create(
ApplyView& view,
beast::Journal journal,
MPTCreateArgs const& args)
{
auto const acct = view().peek(keylet::account(account_));
auto const acct = view.peek(keylet::account(args.account));
if (!acct)
return tecINTERNAL;

if (mPriorBalance < view().fees().accountReserve((*acct)[sfOwnerCount] + 1))
if (args.priorBalance <
view.fees().accountReserve((*acct)[sfOwnerCount] + 1))
return tecINSUFFICIENT_RESERVE;

auto const mptIssuanceKeylet =
keylet::mptIssuance(account_, ctx_.tx.getSeqProxy().value());
keylet::mptIssuance(args.account, args.sequence);

// create the MPTokenIssuance
{
auto const ownerNode = view().dirInsert(
keylet::ownerDir(account_),
auto const ownerNode = view.dirInsert(
keylet::ownerDir(args.account),
mptIssuanceKeylet,
describeOwnerDir(account_));
describeOwnerDir(args.account));

if (!ownerNode)
return tecDIR_FULL;

auto mptIssuance = std::make_shared<SLE>(mptIssuanceKeylet);
(*mptIssuance)[sfFlags] = ctx_.tx.getFlags() & ~tfUniversal;
(*mptIssuance)[sfIssuer] = account_;
(*mptIssuance)[sfFlags] = args.flags & ~tfUniversal;
(*mptIssuance)[sfIssuer] = args.account;
(*mptIssuance)[sfOutstandingAmount] = 0;
(*mptIssuance)[sfOwnerNode] = *ownerNode;
(*mptIssuance)[sfSequence] = ctx_.tx.getSeqProxy().value();
(*mptIssuance)[sfSequence] = args.sequence;

if (auto const max = ctx_.tx[~sfMaximumAmount])
(*mptIssuance)[sfMaximumAmount] = *max;
if (args.maxAmount)
(*mptIssuance)[sfMaximumAmount] = *args.maxAmount;

if (auto const scale = ctx_.tx[~sfAssetScale])
(*mptIssuance)[sfAssetScale] = *scale;
if (args.assetScale)
(*mptIssuance)[sfAssetScale] = *args.assetScale;

if (auto const fee = ctx_.tx[~sfTransferFee])
(*mptIssuance)[sfTransferFee] = *fee;
if (args.transferFee)
(*mptIssuance)[sfTransferFee] = *args.transferFee;

if (auto const metadata = ctx_.tx[~sfMPTokenMetadata])
(*mptIssuance)[sfMPTokenMetadata] = *metadata;
if (args.metadata)
(*mptIssuance)[sfMPTokenMetadata] = *args.metadata;

view().insert(mptIssuance);
view.insert(mptIssuance);
}

// Update owner count.
adjustOwnerCount(view(), acct, 1, j_);
adjustOwnerCount(view, acct, 1, journal);

return tesSUCCESS;
}

TER
MPTokenIssuanceCreate::doApply()
{
auto const& tx = ctx_.tx;
return create(
ctx_.view(),
ctx_.journal,
{.priorBalance = mPriorBalance,
.account = account_,
.sequence = tx.getSeqProxy().value(),
.flags = tx.getFlags(),
.maxAmount = tx[~sfMaximumAmount],
.assetScale = tx[~sfAssetScale],
.transferFee = tx[~sfTransferFee],
.metadata = tx[~sfMPTokenMetadata]});
}

} // namespace ripple
15 changes: 15 additions & 0 deletions src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@

namespace ripple {

struct MPTCreateArgs
{
XRPAmount const& priorBalance;
AccountID const& account;
std::uint32_t sequence;
std::uint32_t flags;
std::optional<std::uint64_t> maxAmount;
std::optional<std::uint8_t> assetScale;
std::optional<std::uint16_t> transferFee;
std::optional<Slice> const& metadata;
};

class MPTokenIssuanceCreate : public Transactor
{
public:
Expand All @@ -38,6 +50,9 @@ class MPTokenIssuanceCreate : public Transactor

TER
doApply() override;

static TER
create(ApplyView& view, beast::Journal journal, MPTCreateArgs const& args);
};

} // namespace ripple
Expand Down
1 change: 1 addition & 0 deletions src/xrpld/app/tx/detail/Payment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <xrpld/app/paths/RippleCalc.h>
#include <xrpld/app/tx/detail/Payment.h>
#include <xrpld/core/Config.h>
#include <xrpld/ledger/View.h>
#include <xrpl/basics/Log.h>
#include <xrpl/protocol/Feature.h>
Expand Down

0 comments on commit 8298f81

Please sign in to comment.