Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 28 additions & 58 deletions include/xrpl/protocol/TxMeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,35 @@

class TxMeta
{
private:
struct CtorHelper
{
explicit CtorHelper() = default;
};
template <class T>
TxMeta(
uint256 const& txID,
std::uint32_t ledger,
T const& data,
CtorHelper);

public:
TxMeta(
uint256 const& transactionID,
std::uint32_t ledger,
std::optional<uint256> parentBatchId = std::nullopt);
TxMeta(uint256 const& transactionID, std::uint32_t ledger);
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);

uint256 const&
getTxID() const
{
return mTransactionID;
return transactionID_;
}
std::uint32_t
getLgrSeq() const
{
return mLedger;
return ledgerSeq_;
}
int
getResult() const
{
return mResult;
return result_;

Check warning on line 54 in include/xrpl/protocol/TxMeta.h

View check run for this annotation

Codecov / codecov/patch

include/xrpl/protocol/TxMeta.h#L54

Added line #L54 was not covered by tests
}
TER
getResultTER() const
{
return TER::fromInt(mResult);
return TER::fromInt(result_);
}
std::uint32_t
getIndex() const
{
return mIndex;
return index_;
}

void
Expand All @@ -104,66 +88,52 @@
STArray&
getNodes()
{
return (mNodes);
return nodes_;
}
STArray const&
getNodes() const
{
return (mNodes);
return nodes_;
}

void
setDeliveredAmount(STAmount const& delivered)
setAdditionalFields(STObject const& obj)
{
mDelivered = delivered;
}
if (obj.isFieldPresent(sfDeliveredAmount))
deliveredAmount_ = obj.getFieldAmount(sfDeliveredAmount);

STAmount
getDeliveredAmount() const
{
XRPL_ASSERT(
hasDeliveredAmount(),
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
return *mDelivered;
if (obj.isFieldPresent(sfParentBatchID))
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
}

bool
hasDeliveredAmount() const
std::optional<STAmount> const&
getDeliveredAmount() const
{
return static_cast<bool>(mDelivered);
return deliveredAmount_;
}

void
setParentBatchId(uint256 const& parentBatchId)
setDeliveredAmount(std::optional<STAmount> const& amount)
{
mParentBatchId = parentBatchId;
deliveredAmount_ = amount;
}

uint256
getParentBatchId() const
{
XRPL_ASSERT(
hasParentBatchId(),
"ripple::TxMeta::getParentBatchId : non-null batch id");
return *mParentBatchId;
}

bool
hasParentBatchId() const
void
setParentBatchID(std::optional<uint256> const& id)
{
return static_cast<bool>(mParentBatchId);
parentBatchID_ = id;
}

private:
uint256 mTransactionID;
std::uint32_t mLedger;
std::uint32_t mIndex;
int mResult;
uint256 transactionID_;
std::uint32_t ledgerSeq_;
std::uint32_t index_;
int result_;

std::optional<STAmount> mDelivered;
std::optional<uint256> mParentBatchId;
std::optional<STAmount> deliveredAmount_;
std::optional<uint256> parentBatchID_;

STArray mNodes;
STArray nodes_;
};

} // namespace ripple
Expand Down
6 changes: 3 additions & 3 deletions src/libxrpl/ledger/ApplyStateTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ ApplyStateTable::apply(
std::optional<TxMeta> metadata;
if (!to.open() || isDryRun)
{
TxMeta meta(tx.getTransactionID(), to.seq(), parentBatchId);
TxMeta meta(tx.getTransactionID(), to.seq());

if (deliver)
meta.setDeliveredAmount(*deliver);
meta.setDeliveredAmount(deliver);
meta.setParentBatchID(parentBatchId);

Mods newMod;
for (auto& item : items_)
Expand Down
123 changes: 47 additions & 76 deletions src/libxrpl/protocol/TxMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,76 +39,46 @@

namespace ripple {

template <class T>
TxMeta::TxMeta(
uint256 const& txid,
std::uint32_t ledger,
T const& data,
CtorHelper)
: mTransactionID(txid), mLedger(ledger), mNodes(sfAffectedNodes, 32)
{
SerialIter sit(makeSlice(data));

STObject obj(sit, sfMetadata);
mResult = obj.getFieldU8(sfTransactionResult);
mIndex = obj.getFieldU32(sfTransactionIndex);
mNodes = *dynamic_cast<STArray*>(&obj.getField(sfAffectedNodes));

if (obj.isFieldPresent(sfDeliveredAmount))
setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));

if (obj.isFieldPresent(sfParentBatchID))
setParentBatchId(obj.getFieldH256(sfParentBatchID));
}

TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
: mTransactionID(txid)
, mLedger(ledger)
, mNodes(obj.getFieldArray(sfAffectedNodes))
: transactionID_(txid)
, ledgerSeq_(ledger)
, nodes_(obj.getFieldArray(sfAffectedNodes))
{
mResult = obj.getFieldU8(sfTransactionResult);
mIndex = obj.getFieldU32(sfTransactionIndex);
result_ = obj.getFieldU8(sfTransactionResult);
index_ = obj.getFieldU32(sfTransactionIndex);

auto affectedNodes =
dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
XRPL_ASSERT(
affectedNodes,
"ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
if (affectedNodes)
mNodes = *affectedNodes;

if (obj.isFieldPresent(sfDeliveredAmount))
setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));
nodes_ = *affectedNodes;

if (obj.isFieldPresent(sfParentBatchID))
setParentBatchId(obj.getFieldH256(sfParentBatchID));
setAdditionalFields(obj);
}

TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
: TxMeta(txid, ledger, vec, CtorHelper())
: transactionID_(txid), ledgerSeq_(ledger), nodes_(sfAffectedNodes, 32)
{
}
SerialIter sit(makeSlice(vec));

TxMeta::TxMeta(
uint256 const& txid,
std::uint32_t ledger,
std::string const& data)
: TxMeta(txid, ledger, data, CtorHelper())
{
STObject obj(sit, sfMetadata);
result_ = obj.getFieldU8(sfTransactionResult);
index_ = obj.getFieldU32(sfTransactionIndex);
nodes_ = obj.getFieldArray(sfAffectedNodes);

setAdditionalFields(obj);
}

TxMeta::TxMeta(
uint256 const& transactionID,
std::uint32_t ledger,
std::optional<uint256> parentBatchId)
: mTransactionID(transactionID)
, mLedger(ledger)
, mIndex(static_cast<std::uint32_t>(-1))
, mResult(255)
, mParentBatchId(parentBatchId)
, mNodes(sfAffectedNodes)
TxMeta::TxMeta(uint256 const& transactionID, std::uint32_t ledger)
: transactionID_(transactionID)
, ledgerSeq_(ledger)
, index_(std::numeric_limits<std::uint32_t>::max())
, result_(255)
, nodes_(sfAffectedNodes)
{
mNodes.reserve(32);
nodes_.reserve(32);
}

void
Expand All @@ -118,7 +88,7 @@ TxMeta::setAffectedNode(
std::uint16_t nodeType)
{
// make sure the node exists and force its type
for (auto& n : mNodes)
for (auto& n : nodes_)
{
if (n.getFieldH256(sfLedgerIndex) == node)
{
Expand All @@ -128,8 +98,8 @@ TxMeta::setAffectedNode(
}
}

mNodes.push_back(STObject(type));
STObject& obj = mNodes.back();
nodes_.push_back(STObject(type));
STObject& obj = nodes_.back();

XRPL_ASSERT(
obj.getFName() == type,
Expand All @@ -146,14 +116,15 @@ TxMeta::getAffectedAccounts() const

// This code should match the behavior of the JS method:
// Meta#getAffectedAccounts
for (auto const& it : mNodes)
for (auto const& node : nodes_)
{
int index = it.getFieldIndex(
(it.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
int index = node.getFieldIndex(
(node.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);

if (index != -1)
{
auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
auto const* inner =
dynamic_cast<STObject const*>(&node.peekAtIndex(index));
XRPL_ASSERT(
inner,
"ripple::getAffectedAccounts : STObject type cast succeeded");
Expand Down Expand Up @@ -213,13 +184,13 @@ STObject&
TxMeta::getAffectedNode(SLE::ref node, SField const& type)
{
uint256 index = node->key();
for (auto& n : mNodes)
for (auto& n : nodes_)
{
if (n.getFieldH256(sfLedgerIndex) == index)
return n;
}
mNodes.push_back(STObject(type));
STObject& obj = mNodes.back();
nodes_.push_back(STObject(type));
STObject& obj = nodes_.back();

XRPL_ASSERT(
obj.getFName() == type,
Expand All @@ -233,45 +204,45 @@ TxMeta::getAffectedNode(SLE::ref node, SField const& type)
STObject&
TxMeta::getAffectedNode(uint256 const& node)
{
for (auto& n : mNodes)
for (auto& n : nodes_)
{
if (n.getFieldH256(sfLedgerIndex) == node)
return n;
}
// LCOV_EXCL_START
UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
Throw<std::runtime_error>("Affected node not found");
return *(mNodes.begin()); // Silence compiler warning.
return *(nodes_.begin()); // Silence compiler warning.
// LCOV_EXCL_STOP
}

STObject
TxMeta::getAsObject() const
{
STObject metaData(sfTransactionMetaData);
XRPL_ASSERT(mResult != 255, "ripple::TxMeta::getAsObject : result is set");
metaData.setFieldU8(sfTransactionResult, mResult);
metaData.setFieldU32(sfTransactionIndex, mIndex);
metaData.emplace_back(mNodes);
if (hasDeliveredAmount())
metaData.setFieldAmount(sfDeliveredAmount, getDeliveredAmount());
XRPL_ASSERT(result_ != 255, "ripple::TxMeta::getAsObject : result_ is set");
metaData.setFieldU8(sfTransactionResult, result_);
metaData.setFieldU32(sfTransactionIndex, index_);
metaData.emplace_back(nodes_);
if (deliveredAmount_.has_value())
metaData.setFieldAmount(sfDeliveredAmount, *deliveredAmount_);

if (hasParentBatchId())
metaData.setFieldH256(sfParentBatchID, getParentBatchId());
if (parentBatchID_.has_value())
metaData.setFieldH256(sfParentBatchID, *parentBatchID_);

return metaData;
}

void
TxMeta::addRaw(Serializer& s, TER result, std::uint32_t index)
{
mResult = TERtoInt(result);
mIndex = index;
result_ = TERtoInt(result);
index_ = index;
XRPL_ASSERT(
(mResult == 0) || ((mResult > 100) && (mResult <= 255)),
(result_ == 0) || ((result_ > 100) && (result_ <= 255)),
"ripple::TxMeta::addRaw : valid TER input");

mNodes.sort([](STObject const& o1, STObject const& o2) {
nodes_.sort([](STObject const& o1, STObject const& o2) {
return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);
});

Expand Down
5 changes: 3 additions & 2 deletions src/xrpld/rpc/detail/DeliveredAmount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ getDeliveredAmount(
if (!serializedTx)
return {};

if (transactionMeta.hasDeliveredAmount())
if (auto const& deliveredAmount = transactionMeta.getDeliveredAmount();
deliveredAmount.has_value())
{
return transactionMeta.getDeliveredAmount();
return *deliveredAmount;
}

if (serializedTx->isFieldPresent(sfAmount))
Expand Down