Add additional checks for emitted txns

This commit is contained in:
Richard Holland
2024-01-17 15:39:02 +00:00
parent de522ac4ae
commit 17ccec9ac5
5 changed files with 44 additions and 2 deletions

View File

@@ -648,6 +648,45 @@ Transactor::checkPriorTxAndLastLedger(PreclaimContext const& ctx)
if (ctx.view.txExists(ctx.tx.getTransactionID()))
return tefALREADY;
if (hook::isEmittedTxn(ctx.tx) &&
ctx.view.rules().enabled(featureHooks) &&
ctx.view.rules().enabled(fixXahauV2))
{
// check if the emitted txn exists on ledger and is in the emission directory
// if not that's a re-apply so discard
auto const kl = keylet::emittedTxn(ctx.tx.getTransactionID());
auto const sleE = ctx.view.read(kl);
if (!sleE)
return tefNONDIR_EMIT;
// lookup the page
uint64_t const page = sleE->getFieldU64(sfOwnerNode);
auto node = ctx.view.read(keylet::page(keylet::emittedDir(), page));
if (!node)
{
JLOG(ctx.j.warn())
<< "applyTransaction: orphaned emitted txn detected. keylet="
<< to_string(kl.key);
// RH TODO: work out how to safely delete the object
return tefNONDIR_EMIT;
}
auto entries = node->getFieldV256(sfIndexes);
auto it = std::find(entries.begin(), entries.end(), kl.key);
if (entries.end() == it)
{
JLOG(ctx.j.warn())
<< "applyTransaction: orphaned emitted txn detected (2). keylet="
<< to_string(kl.key);
// RH TODO: work out how to safely delete the object
return tefNONDIR_EMIT;
}
}
return tesSUCCESS;
}

View File

@@ -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 = 66;
static constexpr std::size_t numFeatures = 67;
/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
@@ -354,6 +354,7 @@ extern uint256 const featureImport;
extern uint256 const featureXahauGenesis;
extern uint256 const featureHooksUpdate1;
extern uint256 const fixXahauV1;
extern uint256 const fixXahauV2;
} // namespace ripple

View File

@@ -183,6 +183,7 @@ enum TEFcodes : TERUnderlyingType {
tefNFTOKEN_IS_NOT_TRANSFERABLE,
tefPAST_IMPORT_SEQ,
tefPAST_IMPORT_VL_SEQ,
tefNONDIR_EMIT,
};
//------------------------------------------------------------------------------

View File

@@ -460,7 +460,7 @@ REGISTER_FEATURE(Import, Supported::yes, VoteBehavior::De
REGISTER_FEATURE(XahauGenesis, Supported::yes, VoteBehavior::DefaultYes);
REGISTER_FEATURE(HooksUpdate1, Supported::yes, VoteBehavior::DefaultYes);
REGISTER_FIX (fixXahauV1, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FIX (fixXahauV2, Supported::yes, VoteBehavior::DefaultNo);
// The following amendments are obsolete, but must remain supported
// because they could potentially get enabled.

View File

@@ -115,6 +115,7 @@ transResults()
MAKE_ERROR(tefTOO_BIG, "Transaction affects too many items."),
MAKE_ERROR(tefNO_TICKET, "Ticket is not in ledger."),
MAKE_ERROR(tefNFTOKEN_IS_NOT_TRANSFERABLE, "The specified NFToken is not transferable."),
MAKE_ERROR(tefNONDIR_EMIT, "An emitted txn was injected into the ledger without a corresponding directory entry."),
MAKE_ERROR(telLOCAL_ERROR, "Local failure."),
MAKE_ERROR(telBAD_DOMAIN, "Domain too long."),