Skip to content

Commit

Permalink
initial DID implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mvadari committed Jul 31, 2023
1 parent aded4a7 commit f3487a4
Show file tree
Hide file tree
Showing 21 changed files with 761 additions and 12 deletions.
2 changes: 2 additions & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ target_sources (rippled PRIVATE
src/ripple/app/tx/impl/CreateTicket.cpp
src/ripple/app/tx/impl/DeleteAccount.cpp
src/ripple/app/tx/impl/DepositPreauth.cpp
src/ripple/app/tx/impl/DID.cpp
src/ripple/app/tx/impl/Escrow.cpp
src/ripple/app/tx/impl/InvariantCheck.cpp
src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp
Expand Down Expand Up @@ -760,6 +761,7 @@ if (tests)
src/test/app/DeliverMin_test.cpp
src/test/app/DepositAuth_test.cpp
src/test/app/Discrepancy_test.cpp
src/test/app/DID_test.cpp
src/test/app/DNS_test.cpp
src/test/app/Escrow_test.cpp
src/test/app/FeeVote_test.cpp
Expand Down
207 changes: 207 additions & 0 deletions src/ripple/app/tx/impl/DID.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#include <ripple/app/tx/impl/DID.h>

#include <ripple/basics/Log.h>
#include <ripple/ledger/ApplyView.h>
#include <ripple/ledger/View.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/st.h>

namespace ripple {

/*
DID
======
TODO: add docs here
*/

//------------------------------------------------------------------------------

NotTEC
DIDSet::preflight(PreflightContext const& ctx)
{
if (!ctx.rules.enabled(featureDID))
return temDISABLED;

if (ctx.tx.getFlags() & tfUniversalMask)
return temINVALID_FLAG;

if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
return ret;

if (!ctx.tx.isFieldPresent(sfURI) && !ctx.tx.isFieldPresent(sfData))
return temEMPTY_DID;

if (ctx.tx.isFieldPresent(sfURI) && ctx.tx[sfURI].empty() &&
ctx.tx.isFieldPresent(sfData) && ctx.tx[sfData].empty())
return temEMPTY_DID;

return preflight2(ctx);
}

TER
addSLE(
ApplyContext& ctx,
std::shared_ptr<SLE> const& sle,
AccountID const& owner)
{
auto const sleAccount = ctx.view().peek(keylet::account(owner));
if (!sleAccount)
return tefINTERNAL;

// Check reserve availability for new object creation
{
auto const balance = STAmount((*sleAccount)[sfBalance]).xrp();
auto const reserve =
ctx.view().fees().accountReserve((*sleAccount)[sfOwnerCount] + 1);

if (balance < reserve)
return tecINSUFFICIENT_RESERVE;
}

// Add ledger object to ledger
ctx.view().insert(sle);

// Add ledger object to owner's page
{
auto page = ctx.view().dirInsert(
keylet::ownerDir(owner), sle->key(), describeOwnerDir(owner));
if (!page)
return tecDIR_FULL;
(*sle)[sfOwnerNode] = *page;
}
adjustOwnerCount(ctx.view(), sleAccount, 1, ctx.journal);
ctx.view().update(sleAccount);

return tesSUCCESS;
}

TER
DIDSet::doApply()
{
// Edit ledger object if it already exists
Keylet const didKeylet = keylet::did(account_);
if (auto const sleDID = ctx_.view().peek(didKeylet))
{
if (auto const uri = ctx_.tx[~sfURI])
{
if (uri->empty())
{
sleDID->makeFieldAbsent(sfURI);
}
else
{
(*sleDID)[sfURI] = *uri;
}
}
if (auto const data = ctx_.tx[~sfData])
{
if (data->empty())
{
sleDID->makeFieldAbsent(sfData);
}
else
{
(*sleDID)[sfData] = *data;
}
}
if (!sleDID->isFieldPresent(sfURI) && !sleDID->isFieldPresent(sfData))
{
return tecEMPTY_DID;
}
ctx_.view().update(sleDID);
return tesSUCCESS;
}

// Create new ledger object otherwise
auto const sleDID = std::make_shared<SLE>(didKeylet);
(*sleDID)[sfAccount] = account_;
if (auto const uri = ctx_.tx[~sfURI]; uri.has_value() && !uri->empty())
(*sleDID)[sfURI] = uri.value();
if (auto const data = ctx_.tx[~sfData]; data.has_value() && !data->empty())
(*sleDID)[sfData] = data.value();

if (auto const ret = addSLE(ctx_, sleDID, account_); !isTesSuccess(ret))
return ret;

return tesSUCCESS;
}

NotTEC
DIDDelete::preflight(PreflightContext const& ctx)
{
if (!ctx.rules.enabled(featureDID))
return temDISABLED;

if (ctx.tx.getFlags() & tfUniversalMask)
return temINVALID_FLAG;

if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
return ret;

return preflight2(ctx);
}

TER
deleteSLE(ApplyContext& ctx, Keylet sleKeylet, AccountID const owner)
{
auto const sle = ctx.view().peek(sleKeylet);
if (!sle)
return tecNO_ENTRY;

// Remove object from owner directory
{
auto const page = (*sle)[sfOwnerNode];
if (!ctx.view().dirRemove(
keylet::ownerDir(owner), page, sleKeylet.key, true))
{
JLOG(ctx.journal.fatal())
<< "Unable to delete DID Token from owner.";
return tefBAD_LEDGER;
}
}

auto const sleOwner = ctx.view().peek(keylet::account(owner));
adjustOwnerCount(ctx.view(), sleOwner, -1, ctx.journal);
ctx.view().update(sleOwner);

// Remove object from ledger
ctx.view().erase(sle);
return tesSUCCESS;
}

TER
DIDDelete::doApply()
{
AccountID const account = ctx_.tx[sfAccount];
auto const didKeylet = keylet::did(account);

if (auto const ret = deleteSLE(ctx_, didKeylet, account_);
!isTesSuccess(ret))
return ret;

return tesSUCCESS;
}

} // namespace ripple
63 changes: 63 additions & 0 deletions src/ripple/app/tx/impl/DID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#ifndef RIPPLE_TX_DID_H_INCLUDED
#define RIPPLE_TX_DID_H_INCLUDED

#include <ripple/app/tx/impl/Transactor.h>

namespace ripple {

class DIDSet : public Transactor
{
public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};

explicit DIDSet(ApplyContext& ctx) : Transactor(ctx)
{
}

static NotTEC
preflight(PreflightContext const& ctx);

TER
doApply() override;
};

//------------------------------------------------------------------------------

class DIDDelete : public Transactor
{
public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};

explicit DIDDelete(ApplyContext& ctx) : Transactor(ctx)
{
}

static NotTEC
preflight(PreflightContext const& ctx);

TER
doApply() override;
};

} // namespace ripple

#endif
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 @@ -380,6 +380,7 @@ LedgerEntryTypesMatch::visitEntry(
case ltNFTOKEN_PAGE:
case ltNFTOKEN_OFFER:
case ltAMM:
case ltDID:
break;
default:
invalidTypeAdded_ = true;
Expand Down
21 changes: 21 additions & 0 deletions src/ripple/app/tx/impl/applySteps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <ripple/app/tx/impl/CreateCheck.h>
#include <ripple/app/tx/impl/CreateOffer.h>
#include <ripple/app/tx/impl/CreateTicket.h>
#include <ripple/app/tx/impl/DID.h>
#include <ripple/app/tx/impl/DeleteAccount.h>
#include <ripple/app/tx/impl/DepositPreauth.h>
#include <ripple/app/tx/impl/Escrow.h>
Expand Down Expand Up @@ -165,6 +166,10 @@ invoke_preflight(PreflightContext const& ctx)
return invoke_preflight_helper<AMMVote>(ctx);
case ttAMM_BID:
return invoke_preflight_helper<AMMBid>(ctx);
case ttDID_SET:
return invoke_preflight_helper<DIDSet>(ctx);
case ttDID_DELETE:
return invoke_preflight_helper<DIDDelete>(ctx);
default:
assert(false);
return {temUNKNOWN, TxConsequences{temUNKNOWN}};
Expand Down Expand Up @@ -278,6 +283,10 @@ invoke_preclaim(PreclaimContext const& ctx)
return invoke_preclaim<AMMVote>(ctx);
case ttAMM_BID:
return invoke_preclaim<AMMBid>(ctx);
case ttDID_SET:
return invoke_preclaim<DIDSet>(ctx);
case ttDID_DELETE:
return invoke_preclaim<DIDDelete>(ctx);
default:
assert(false);
return temUNKNOWN;
Expand Down Expand Up @@ -353,6 +362,10 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx)
return AMMVote::calculateBaseFee(view, tx);
case ttAMM_BID:
return AMMBid::calculateBaseFee(view, tx);
case ttDID_SET:
return DIDSet::calculateBaseFee(view, tx);
case ttDID_DELETE:
return DIDDelete::calculateBaseFee(view, tx);
default:
assert(false);
return XRPAmount{0};
Expand Down Expand Up @@ -529,6 +542,14 @@ invoke_apply(ApplyContext& ctx)
AMMBid p(ctx);
return p();
}
case ttDID_SET: {
DIDSet p(ctx);
return p();
}
case ttDID_DELETE: {
DIDDelete p(ctx);
return p();
}
default:
assert(false);
return {temUNKNOWN, false};
Expand Down
3 changes: 2 additions & 1 deletion src/ripple/protocol/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace detail {
// 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
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 61;
static constexpr std::size_t numFeatures = 62;

/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
Expand Down Expand Up @@ -348,6 +348,7 @@ extern uint256 const fixNonFungibleTokensV1_2;
extern uint256 const fixNFTokenRemint;
extern uint256 const fixReducedOffersV1;
extern uint256 const featureClawback;
extern uint256 const featureDID;

} // namespace ripple

Expand Down
3 changes: 3 additions & 0 deletions src/ripple/protocol/Indexes.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ amm(Issue const& issue1, Issue const& issue2) noexcept;
Keylet
amm(uint256 const& amm) noexcept;

Keylet
did(AccountID const& account) noexcept;

} // namespace keylet

// Everything below is deprecated and should be removed in favor of keylets:
Expand Down
6 changes: 6 additions & 0 deletions src/ripple/protocol/LedgerFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ enum LedgerEntryType : std::uint16_t
*/
ltAMM = 0x0079,

/** The ledger object which tracks the DID.
\sa keylet::did
*/
ltDID = 0x0049,

//---------------------------------------------------------------------------
/** A special type, matching any ledger entry type.
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/SField.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ extern SF_VL const sfCreateCode;
extern SF_VL const sfMemoType;
extern SF_VL const sfMemoData;
extern SF_VL const sfMemoFormat;
extern SF_VL const sfData;

// variable length (uncommon)
extern SF_VL const sfFulfillment;
Expand Down
Loading

0 comments on commit f3487a4

Please sign in to comment.