rename transactor

This commit is contained in:
Denis Angell
2024-06-18 10:34:08 +02:00
parent dddc7a6f72
commit bae099ee63
12 changed files with 98 additions and 104 deletions

View File

@@ -449,7 +449,7 @@ target_sources (rippled PRIVATE
src/ripple/app/tx/impl/NFTokenMint.cpp
src/ripple/app/tx/impl/OfferStream.cpp
src/ripple/app/tx/impl/OptionCreate.cpp
src/ripple/app/tx/impl/OptionExecute.cpp
src/ripple/app/tx/impl/OptionExercise.cpp
src/ripple/app/tx/impl/OptionList.cpp
src/ripple/app/tx/impl/PayChan.cpp
src/ripple/app/tx/impl/Payment.cpp

View File

@@ -124,7 +124,7 @@ sealOption(
bool const _isSell = (flags & tfAction) != 0;
// Skip Sealed Options
if (sleItem->getFieldU32(sfToSeal) == 0)
if (sleItem->getFieldU32(sfOpenInterest) == 0)
{
continue;
}
@@ -165,8 +165,7 @@ OptionCreate::doApply()
std::uint32_t const quantity = ctx_.tx.getFieldU32(sfQuantity);
std::optional<uint256> const swapID = ctx_.tx[~sfSwapID];
STAmount const totalPremium =
STAmount(premium.issue(), (premium.mantissa() * quantity));
STAmount const totalPremium = mulRound(premium, STAmount(premium.issue(), quantity), premium.issue(), false);
auto sleSrcAcc = sb.peek(keylet::account(srcAccID));
if (!sleSrcAcc)
@@ -184,9 +183,7 @@ OptionCreate::doApply()
STAmount const quantityShares = STAmount(Issue(currency, issuer), quantity);
if (strikePrice.issue() != totalPremium.issue() || strikePrice.issue() != totalPremium.issue())
{
return temBAD_ISSUER;
}
bool const isPut = (flags & tfType) != 0;
bool const isSell = (flags & tfAction) != 0;
@@ -218,8 +215,8 @@ OptionCreate::doApply()
auto sealedKeylet = ripple::keylet::unchecked(*sealID);
auto sealedOption = sb.peek(sealedKeylet);
sealedOption->setFieldH256(sfSwapID, optionOfferKeylet.key);
uint32_t currSealed = sealedOption->getFieldU32(sfToSeal);
sealedOption->setFieldU32(sfToSeal, currSealed - quantity);
uint32_t currSealed = sealedOption->getFieldU32(sfOpenInterest);
sealedOption->setFieldU32(sfOpenInterest, currSealed - quantity);
oppAccID = sealedOption->getAccountID(sfOwner);
sb.update(sealedOption);
}
@@ -265,14 +262,14 @@ OptionCreate::doApply()
optionOffer->setFieldU64(sfOwnerNode, *page);
optionOffer->setFieldH256(sfOptionID, optionID);
optionOffer->setFieldU32(sfQuantity, quantity);
optionOffer->setFieldU32(sfToSeal, quantity);
optionOffer->setFieldU32(sfOpenInterest, quantity);
optionOffer->setFieldAmount(sfAmount, premium); // Premium
optionOffer->setFieldAmount(sfLockedBalance, STAmount(0)); // Locked
if (sealID)
{
JLOG(j.warn()) << "Updating Option Offer: sealID";
optionOffer->setFieldH256(sfSwapID, *sealID);
optionOffer->setFieldU32(sfToSeal, 0);
optionOffer->setFieldU32(sfOpenInterest, 0);
}
if (isSell)
{
@@ -402,28 +399,29 @@ OptionCreate::doApply()
else
{
// // 1. & 2.
// TER canBuyerXfer = trustTransferAllowed(
// sb,
// std::vector<AccountID>{srcAccID, oppAccID},
// totalPremium.issue(),
// j);
TER canBuyerXfer = trustTransferAllowed(
sb,
std::vector<AccountID>{srcAccID, oppAccID},
totalPremium.issue(),
j);
// if (!isTesSuccess(canBuyerXfer))
// {
// return canBuyerXfer;
// }
if (!isTesSuccess(canBuyerXfer))
{
return canBuyerXfer;
}
// STAmount availableBuyerFunds{accountFunds(
// sb, srcAccID, totalPremium, fhZERO_IF_FROZEN, j)};
STAmount availableBuyerFunds{accountFunds(
sb, srcAccID, totalPremium, fhZERO_IF_FROZEN, j)};
// if (availableBuyerFunds < totalPremium)
// return tecUNFUNDED_PAYMENT;
// if (TER result = accountSend(
// sb, srcAccID, oppAccID, totalPremium, j, true);
// !isTesSuccess(result))
// return result;
return tecINTERNAL;
JLOG(j.warn()) << "availableBuyerFunds: " << availableBuyerFunds << "/n";
JLOG(j.warn()) << "totalPremium: " << totalPremium << "/n";
if (availableBuyerFunds < totalPremium)
return tecUNFUNDED_PAYMENT;
if (TER result = accountSend(sb, srcAccID, oppAccID, totalPremium, j, true); !isTesSuccess(result))
return result;
}
sb.update(sleOppAcc);
@@ -453,9 +451,9 @@ OptionCreate::doApply()
if (availableBuyerFunds < quantityShares)
return tecUNFUNDED_PAYMENT;
std::shared_ptr<SLE> sleLine = sb.peek(keylet::line(srcAccID, quantityShares.getIssuer(), quantityShares.getCurrency()));
std::shared_ptr<SLE> sleLine = ctx_.view().peek(keylet::line(srcAccID, quantityShares.getIssuer(), quantityShares.getCurrency()));
if (TER const result = trustAdjustLockedBalance(ctx_.view(), sleLine, quantityShares, 1, ctx_.journal, true); !isTesSuccess(result))
if (TER const result = trustAdjustLockedBalance(ctx_.view(), sleLine, quantityShares, 1, ctx_.journal, WetRun); !isTesSuccess(result))
return result;
}
}

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <ripple/app/tx/impl/OptionExecute.h>
#include <ripple/app/tx/impl/OptionExercise.h>
#include <ripple/basics/Log.h>
#include <ripple/ledger/ApplyView.h>
#include <ripple/ledger/View.h>
@@ -29,13 +29,13 @@
namespace ripple {
TxConsequences
OptionExecute::makeTxConsequences(PreflightContext const& ctx)
OptionExercise::makeTxConsequences(PreflightContext const& ctx)
{
return TxConsequences{ctx.tx, TxConsequences::normal};
}
NotTEC
OptionExecute::preflight(PreflightContext const& ctx)
OptionExercise::preflight(PreflightContext const& ctx)
{
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
return ret;
@@ -50,12 +50,12 @@ OptionExecute::preflight(PreflightContext const& ctx)
TER
OptionExecute::doApply()
OptionExercise::doApply()
{
if (!view().rules().enabled(featureOptions))
return temDISABLED;
Sandbox sb(&ctx_.view());
// Sandbox sb(&ctx_.view());
beast::Journal const& j = ctx_.journal;
@@ -64,24 +64,24 @@ OptionExecute::doApply()
uint256 const offerID = ctx_.tx.getFieldH256(sfSwapID);
auto const flags = ctx_.tx.getFlags();
auto sleSrcAcc = sb.peek(keylet::account(srcAccID));
auto sleSrcAcc = ctx_.view().peek(keylet::account(srcAccID));
if (!sleSrcAcc)
return terNO_ACCOUNT;
auto optionOfferKeylet = ripple::keylet::unchecked(offerID);
auto sleOptionOffer = sb.peek(optionOfferKeylet);
auto sleOptionOffer = ctx_.view().peek(optionOfferKeylet);
if (!sleOptionOffer)
return tecNO_TARGET;
AccountID const ownrAccID = sleOptionOffer->getAccountID(sfOwner);
auto const sealedID = sleOptionOffer->getFieldH256(sfSwapID);
auto oppOfferKeylet = ripple::keylet::unchecked(sealedID);
auto sleSealedOffer = sb.peek(oppOfferKeylet);
auto sleSealedOffer = ctx_.view().peek(oppOfferKeylet);
if (!sleSealedOffer)
return tecNO_TARGET;
AccountID const oppAccID = sleSealedOffer->getAccountID(sfOwner);
auto sleOppAcc = sb.peek(keylet::account(oppAccID));
auto sleOppAcc = ctx_.view().peek(keylet::account(oppAccID));
if (!sleOppAcc)
return terNO_ACCOUNT;
@@ -89,31 +89,32 @@ OptionExecute::doApply()
bool const isPut = (optionFlags & tfType) != 0;
bool const isSell = (optionFlags & tfAction) != 0;
auto sleOption = sb.peek(keylet::unchecked(optionID));
auto sleOption = ctx_.view().peek(keylet::unchecked(optionID));
if (!sleOption)
return tecINTERNAL;
STAmount const strikePrice = sleOption->getFieldAmount(sfStrikePrice);
STAmount const quantityShares = sleSealedOffer->getFieldAmount(sfLockedBalance);
std::uint32_t const quantity = sleOptionOffer->getFieldU32(sfQuantity);
STAmount const totalValue = STAmount(strikePrice.issue(), (strikePrice.mantissa() * quantity));
STAmount const totalValue = mulRound(strikePrice, STAmount(strikePrice.issue(), quantity), strikePrice.issue(), false);
JLOG(j.warn()) << "OptionExecute: QUANTITY SHARES" << quantityShares << "\n";
JLOG(j.warn()) << "OptionExecute: TOTAL VALUE" << totalValue << "\n";
JLOG(j.warn()) << "OptionExercise: QUANTITY SHARES" << quantityShares << "\n";
JLOG(j.warn()) << "OptionExercise: TOTAL VALUE" << totalValue << "\n";
if (flags & tfOptionExpire)
{
JLOG(j.warn()) << "OptionExecute: EXPIRE OPTION";
sb.erase(sleSealedOffer);
sb.erase(sleOptionOffer);
sb.apply(ctx_.rawView());
JLOG(j.warn()) << "OptionExercise: EXPIRE OPTION";
ctx_.view().erase(sleSealedOffer);
ctx_.view().erase(sleOptionOffer);
// sb.apply(ctx_.rawView());
return tesSUCCESS;
}
switch (isPut)
{
case 0: {
JLOG(j.warn()) << "OptionExecute: EXERCISE CALL";
JLOG(j.warn()) << "OptionExercise: EXERCISE CALL";
STAmount hBalance = mSourceBalance;
@@ -129,7 +130,6 @@ OptionExecute::doApply()
if (hBalance < beast::zero || hBalance > mSourceBalance)
return tecINTERNAL;
// 2.
STAmount wBalance = sleOppAcc->getFieldAmount(sfBalance);
STAmount prior = wBalance;
@@ -142,7 +142,7 @@ OptionExecute::doApply()
{
// 1. & 2.
TER canBuyerXfer = trustTransferAllowed(
sb,
ctx_.view(),
std::vector<AccountID>{srcAccID, oppAccID},
totalValue.issue(),
j);
@@ -153,13 +153,13 @@ OptionExecute::doApply()
}
STAmount availableBuyerFunds{accountFunds(
sb, srcAccID, totalValue, fhZERO_IF_FROZEN, j)};
ctx_.view(), srcAccID, totalValue, fhZERO_IF_FROZEN, j)};
if (availableBuyerFunds < totalValue)
return tecUNFUNDED_PAYMENT;
if (TER result = accountSend(
sb, srcAccID, oppAccID, totalValue, j, true);
ctx_.view(), srcAccID, oppAccID, totalValue, j, true);
!isTesSuccess(result))
return result;
}
@@ -175,38 +175,34 @@ OptionExecute::doApply()
}
else
{
AccountID const issuerAccID = totalValue.getIssuer();
{
// check permissions
if (issuerAccID == oppAccID || issuerAccID == srcAccID)
{
// no permission check needed when the issuer sends out or a
// subscriber sends back RH TODO: move this condition into
// trustTransferAllowed, guarded by an amendment
}
else if (TER canXfer = trustTransferAllowed(
sb,
std::vector<AccountID>{oppAccID, srcAccID},
quantityShares.issue(),
j);
!isTesSuccess(canXfer))
return canXfer;
STAmount availableFunds{accountFunds(sb, oppAccID, quantityShares, fhZERO_IF_FROZEN, j)};
if (availableFunds < quantityShares)
return tecUNFUNDED_PAYMENT;
// action the transfer
if (TER result = accountSend(sb, oppAccID, srcAccID, quantityShares, j, true); !isTesSuccess(result))
return result;
}
// Rate lockedRate = ripple::Rate(slep->getFieldU32(sfTransferRate));
// auto const issuerAccID = totalPremium.getIssuer();
// auto const xferRate = transferRate(view(), issuerAccID);
// // // update if issuer rate is less than locked rate
// // if (xferRate < lockedRate)
// // lockedRate = xferRate;
// all the significant complexity of checking the validity of this
// transfer and ensuring the lines exist etc is hidden away in this
// function, all we need to do is call it and return if unsuccessful.
TER const result = trustTransferLockedBalance(
ctx_.view(),
account_, // txn signing account
sleOppAcc, // src account
sleSrcAcc, // dst account
quantityShares, // xfer amount
-1,
parityRate,
j_,
WetRun // wet run;
);
if (!isTesSuccess(result))
return result;
}
break;
}
case 1: {
JLOG(j.warn()) << "OptionExecute: EXERCISE PUT";
JLOG(j.warn()) << "OptionExercise: EXERCISE PUT";
if (isXRP(quantityShares))
{
// add the total value to the holder
@@ -245,16 +241,16 @@ OptionExecute::doApply()
}
// apply
sb.update(sleOppAcc);
sb.update(sleSrcAcc);
sb.erase(sleSealedOffer);
sb.erase(sleOptionOffer);
sb.apply(ctx_.rawView());
ctx_.view().update(sleOppAcc);
ctx_.view().update(sleSrcAcc);
ctx_.view().erase(sleSealedOffer);
ctx_.view().erase(sleOptionOffer);
// sb.apply(ctx_.rawView());
return tesSUCCESS;
}
XRPAmount
OptionExecute::calculateBaseFee(ReadView const& view, STTx const& tx)
OptionExercise::calculateBaseFee(ReadView const& view, STTx const& tx)
{
return Transactor::calculateBaseFee(view, tx);
}

View File

@@ -27,12 +27,12 @@
namespace ripple {
class OptionExecute : public Transactor
class OptionExercise : public Transactor
{
public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
explicit OptionExecute(ApplyContext& ctx) : Transactor(ctx)
explicit OptionExercise(ApplyContext& ctx) : Transactor(ctx)
{
}

View File

@@ -39,7 +39,7 @@
#include <ripple/app/tx/impl/NFTokenCreateOffer.h>
#include <ripple/app/tx/impl/NFTokenMint.h>
#include <ripple/app/tx/impl/OptionCreate.h>
#include <ripple/app/tx/impl/OptionExecute.h>
#include <ripple/app/tx/impl/OptionExercise.h>
#include <ripple/app/tx/impl/OptionList.h>
#include <ripple/app/tx/impl/PayChan.h>
#include <ripple/app/tx/impl/Payment.h>
@@ -129,8 +129,8 @@ invoke_preflight(PreflightContext const& ctx)
return invoke_preflight_helper<EscrowCancel>(ctx);
case ttOPTION_CREATE:
return invoke_preflight_helper<OptionCreate>(ctx);
case ttOPTION_EXECUTE:
return invoke_preflight_helper<OptionExecute>(ctx);
case ttOPTION_EXERCISE:
return invoke_preflight_helper<OptionExercise>(ctx);
case ttOPTION_LIST:
return invoke_preflight_helper<OptionList>(ctx);
case ttPAYCHAN_CLAIM:
@@ -256,8 +256,8 @@ invoke_preclaim(PreclaimContext const& ctx)
return invoke_preclaim<EscrowCancel>(ctx);
case ttOPTION_CREATE:
return invoke_preclaim<OptionCreate>(ctx);
case ttOPTION_EXECUTE:
return invoke_preclaim<OptionExecute>(ctx);
case ttOPTION_EXERCISE:
return invoke_preclaim<OptionExercise>(ctx);
case ttOPTION_LIST:
return invoke_preclaim<OptionList>(ctx);
case ttPAYCHAN_CLAIM:
@@ -345,8 +345,8 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx)
return EscrowCancel::calculateBaseFee(view, tx);
case ttOPTION_CREATE:
return OptionCreate::calculateBaseFee(view, tx);
case ttOPTION_EXECUTE:
return OptionExecute::calculateBaseFee(view, tx);
case ttOPTION_EXERCISE:
return OptionExercise::calculateBaseFee(view, tx);
case ttOPTION_LIST:
return OptionList::calculateBaseFee(view, tx);
case ttPAYCHAN_CLAIM:
@@ -496,8 +496,8 @@ invoke_apply(ApplyContext& ctx)
OptionCreate p(ctx);
return p();
}
case ttOPTION_EXECUTE: {
OptionExecute p(ctx);
case ttOPTION_EXERCISE: {
OptionExercise p(ctx);
return p();
}
case ttOPTION_LIST: {

View File

@@ -411,7 +411,7 @@ extern SF_UINT32 const sfFirstNFTokenSequence;
extern SF_UINT32 const sfImportSequence;
extern SF_UINT32 const sfXahauActivationLgrSeq;
extern SF_UINT32 const sfQuantity;
extern SF_UINT32 const sfToSeal;
extern SF_UINT32 const sfOpenInterest;
// 64-bit integers (common)
extern SF_UINT64 const sfIndexNext;

View File

@@ -187,7 +187,7 @@ enum TxType : std::uint16_t
ttUNL_REPORT = 104,
ttOPTION_LIST = 105,
ttOPTION_CREATE = 106,
ttOPTION_EXECUTE = 107,
ttOPTION_EXERCISE = 107,
};
// clang-format on

View File

@@ -387,7 +387,7 @@ LedgerFormats::LedgerFormats()
{sfLockedBalance, soeREQUIRED}, // Locked Amount
{sfAmount, soeREQUIRED}, // Premium
{sfQuantity, soeREQUIRED}, // Quantity
{sfToSeal, soeREQUIRED}, // To Seal
{sfOpenInterest, soeREQUIRED}, // To Seal
{sfBookDirectory, soeREQUIRED},
{sfBookNode, soeREQUIRED},
{sfSwapID, soeOPTIONAL}, // MatchID

View File

@@ -157,7 +157,7 @@ CONSTRUCT_TYPED_SFIELD(sfLockCount, "LockCount", UINT32,
CONSTRUCT_TYPED_SFIELD(sfFirstNFTokenSequence, "FirstNFTokenSequence", UINT32, 50);
CONSTRUCT_TYPED_SFIELD(sfToSeal, "ToSeal", UINT32, 94);
CONSTRUCT_TYPED_SFIELD(sfOpenInterest, "OpenInterest", UINT32, 94);
CONSTRUCT_TYPED_SFIELD(sfQuantity, "Quantity", UINT32, 95);
CONSTRUCT_TYPED_SFIELD(sfXahauActivationLgrSeq, "XahauActivationLgrSeq",UINT32, 96);
CONSTRUCT_TYPED_SFIELD(sfImportSequence, "ImportSequence", UINT32, 97);

View File

@@ -479,8 +479,8 @@ TxFormats::TxFormats()
},
commonFields);
add(jss::OptionExecute,
ttOPTION_EXECUTE,
add(jss::OptionExercise,
ttOPTION_EXERCISE,
{
{sfOptionID, soeREQUIRED},
{sfSwapID, soeOPTIONAL},

View File

@@ -113,7 +113,7 @@ JSS(OfferCreate); // transaction type.
JSS(OfferSequence); // field.
JSS(Option); // ledger type.
JSS(OptionCreate); // transaction type.
JSS(OptionExecute); // transaction type.
JSS(OptionExercise); // transaction type.
JSS(OptionList); // transaction type.
JSS(OptionOffer); // ledger type.
JSS(Paths); // in/out: TransactionSign

View File

@@ -106,7 +106,7 @@ struct Option_test : public beast::unit_test::suite
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::OptionExecute;
jv[jss::TransactionType] = jss::OptionExercise;
jv[jss::Account] = account.human();
jv[sfOptionID.jsonName] = to_string(optionId);
jv[sfSwapID.jsonName] = to_string(offerId);