Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnxie999 committed Nov 3, 2023
1 parent 724563d commit 5b41e26
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 36 deletions.
144 changes: 109 additions & 35 deletions src/ripple/app/tx/impl/CFTokenAuthorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace ripple {

NotTEC
CFTokenIssuanceCreate::preflight(PreflightContext const& ctx)
CFTokenAuthorize::preflight(PreflightContext const& ctx)
{
if (!ctx.rules.enabled(featureCFTokensV1))
return temDISABLED;
Expand All @@ -38,83 +38,157 @@ CFTokenIssuanceCreate::preflight(PreflightContext const& ctx)
return temINVALID_FLAG;

auto const accountID = ctx.tx[sfAccount];
auto const holder = ctx.tx[~sfCFTokenHolder];
if (holder && accountID == holder)
auto const holderID = ctx.tx[~sfCFTokenholder];
if (holderID && accountID == holderID)
return temMALFORMED;

return preflight2(ctx);
}

TER
CFTokenIssuanceCreate::preclaim(PreclaimContext const& ctx)
CFTokenAuthorize::preclaim(PreclaimContext const& ctx)
{
auto const sleCFT =
auto const sleCftIssuance =
ctx.view.read(keylet::cftIssuance(ctx.tx[sfCFTokenIssuanceID]));
if (!sleCFT)
if (!sleCftIssuance)
return tecOBJECT_NOT_FOUND;

auto const accountID = ctx.tx[sfAccount];
auto const txFlags = ctx.tx[sfFlags];
auto const holder = ctx.tx[~sfCFTokenHolder];
std::uint32_t const cftIssuanceFlags = sleCFT->getFieldU32(sfFlags);
auto const holderID = ctx.tx[~sfCFTokenholder];

if (holderID && !(ctx.view.exists(keylet::account(holderID))))
return tecNO_DST;

std::uint32_t const cftIssuanceFlags = sleCftIssuance->getFieldU32(sfFlags);

// TODO: locate the CFToken Object and check if it exists
auto const sleCft = ;
std::shared_ptr<SLE const> const sleCft;

// If tx is submitted by issuer, they would either try to do the following for allowlisting
// 1. authorize an account
// 2. unauthorize an account
if (accountID == (*sleCFT)[sfIssuer]){
if (accountID == (*sleCftIssuance)[sfIssuer]){

// If tx is submitted by issuer, it only applies for CFT with lsfCFTRequireAuth set
if (!(cftIssuanceFlags & lsfCFTRequireAuth))
return tecNO_PERMISSION;
return tecNO_AUTH;

if (!holder)
return no holder specfied;
if (!holderID)
return temMALFORMED;

sleCft = ctx.view.read(keylet::cftoken(ctx.tx[sfCFTokenIssuanceID], holderID));
if (!sleCft)
return no object;
return tecNO_ENTRY;

// issuer wants to authorize the holder
if (!(txFlags & tfCFTUnathorize)){
//make sure the holder is not already authorized
if ((*sleCft)[sfFlags] & lsfCFTAuthorized)
return flag already set;

auto const sleCftFlags = (*sleCft)[sfFlags];

// issuer wants to unauthorize the holder
if (txFlags & tfCFTUnathorize){
if (!(sleCftFlags & lsfCFTAuthorized))
return temINVALID_FLAG;

}
// unathorize a holder
// authorize a holder
else {
if (!(*sleCft)[sfFlags] & lsfCFTAuthorized)
return cft is not authorized;
//make sure the holder is not already authorized
if (sleCftFlags & lsfCFTAuthorized)
return temMALFORMED;
}


}
// if non-issuer account submits this tx, then they are trying either:
// 1. Unauthorize/delete CFToken
// 2. Use/create CFToken
else{
if(holder)
if(holderID)
return temMALFORMED;

// if holder wants to hold a cft
if (!(txFlags & tfCFTUnathorize)){

if (sleCft)
return already holds object;
sleCft = ctx.view.read(keylet::cftoken(ctx.tx[sfCFTokenIssuanceID], accountID));

// if holder wants to delete/unauthorize a cft
if (txFlags & tfCFTUnathorize){
if (!sleCft)
return tecNO_ENTRY;

if((*sleCft)[sfCFTAmount] != 0)
return tecHAS_OBLIGATIONS;
}
// if holder no longer wants to use cft
// if holder wants to use and create a cft
else{
if((*sleCft)[sfCFTAmount] != 0)
return tecHAS_OBLIGATIONS;
if (sleCft)
return tecDUPLICATE;
}
}
return tesSUCCESS;
}

TER
CFTokenIssuanceCreate::doApply()
CFTokenAuthorize::doApply()
{
auto const cftIssuanceID = ctx_.tx[sfCFTokenIssuanceID];
auto const sleCftIssuance =
view().read(keylet::cftIssuance(cftIssuanceID));
if (!sleCftIssuance)
return tecINTERNAL;


auto const holderID = ctx_.tx[~sfCFTokenholder];
auto const txFlags = ctx.tx[sfFlags];

if (accountID == (*sleCftIssuance)[sfIssuer]){
auto const sleHolder =
}

else{
// if holder wants to delete/unauthorize a cft
if (txFlags & tfCFTUnathorize){
if (!sleCft)
return tecNO_ENTRY;

if((*sleCft)[sfCFTAmount] != 0)
return tecHAS_OBLIGATIONS;
}
// user wants to create a cft
else{
auto const sleAcct = view().peek(keylet::account(account_));
if (!acct)
return tecINTERNAL;

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

auto const cftokenID = keylet::cftoken(cftIssuanceID, account_);


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

if (!ownerNode)
return tecDIR_FULL;


auto const offerNode = view().dirInsert(keylet::cft_dir(cftIssuanceID), cftokenID,
[&cftokenID](std::shared_ptr<SLE> const& sle) {
(*sle)[sfCFTokenIssuanceID] = cftIssuanceID;
});

auto cftoken = std::make_shared<SLE>(cftokenID);
(*cftoken)[sfAccount] = account_;
(*cftoken)[sfCFTokenIssuanceID] = cftIssuanceID;
(*cftoken)[sfFlags] = ctx_.tx.getFlags() & ~tfUniversalMask;
(*cftoken)[sfCFTAmount] = 0;

view().insert(cftoken);


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

}




return tesSUCCESS;
}
Expand Down
1 change: 1 addition & 0 deletions src/ripple/app/tx/impl/InvariantCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ LedgerEntryTypesMatch::visitEntry(
case ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID:
case ltDID:
case ltCFTOKEN_ISSUANCE:
case ltCFTOKEN:
break;
default:
invalidTypeAdded_ = true;
Expand Down
4 changes: 4 additions & 0 deletions src/ripple/protocol/Indexes.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ cftIssuance(uint256 const& issuance)
{
return {ltCFTOKEN_ISSUANCE, issuance};
}

Keylet
cftoken(uint256 const& issuanceID, AccountID const& holder) noexcept;

} // namespace keylet

// Everything below is deprecated and should be removed in favor of keylets:
Expand Down
8 changes: 7 additions & 1 deletion src/ripple/protocol/LedgerFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ enum LedgerEntryType : std::uint16_t
\sa keylet::cftIssuance
*/
ltCFTOKEN_ISSUANCE = 0x007e,

/** A ledger object representing an individual CFToken balance.
\sa keylet::cftoken
*/
ltCFTOKEN = 0x007f,
//---------------------------------------------------------------------------
/** A special type, matching any ledger entry type.
Expand Down Expand Up @@ -320,7 +326,7 @@ enum LedgerSpecificFlags {
lsfCFTCanClawback = 0x00000040,


// ltCFTOKEN_AUTHORIZE
// ltCFTOKEN
lsfCFTAuthorized = 0x00000001,
};

Expand Down
7 changes: 7 additions & 0 deletions src/ripple/protocol/impl/Indexes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum class LedgerNameSpace : std::uint16_t {
XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K',
DID = 'I',
CFTOKEN_ISSUANCE = '~',
CFTOKEN = 'T',

// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
Expand Down Expand Up @@ -453,6 +454,12 @@ cftIssuance(AccountID const& issuer, std::uint32_t seq) noexcept
indexHash(LedgerNameSpace::CFTOKEN_ISSUANCE, issuer, seq)};
}

Keylet
cftoken(uint256 const& issuanceID, AccountID const& holder){
return {
ltCFTOKEN,
indexHash(LedgerNameSpace::CFTOKEN, issuanceID, holder)};
}
} // namespace keylet

} // namespace ripple
11 changes: 11 additions & 0 deletions src/ripple/protocol/impl/LedgerFormats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,17 @@ LedgerFormats::LedgerFormats()
{sfCFTokenMetadata, soeOPTIONAL},
},
commonFields);

add(jss::CFToken,
ltCFTOKEN,
{
{sfAccount, soeREQUIRED},
{sfCFTokenIssuanceID, soeREQUIRED},
{sfCFTAmount, soeREQUIRED},
{sfLockedAmount, soeDEFAULT},
{sfOwnerNode, soeREQUIRED},
},
commonFields);
// clang-format on
}

Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ JSS(Asset2); // in: AMM Asset2
JSS(AuthAccount); // in: AMM Auction Slot
JSS(AuthAccounts); // in: AMM Auction Slot
JSS(Bridge); // ledger type.
JSS(CFToken); // ledger type.
JSS(CFTokenIssuance); // ledger type.
JSS(CFTokenIssuanceCreate); // transaction type.
JSS(CFTokenIssuanceDestroy); // transaction type.
Expand Down

0 comments on commit 5b41e26

Please sign in to comment.