mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
#include <xrpl/ledger/CanonicalTXSet.h>
|
|
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/beast/utility/Zero.h>
|
|
#include <xrpl/protocol/AccountID.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STTx.h>
|
|
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
namespace xrpl {
|
|
|
|
bool
|
|
operator<(CanonicalTXSet::Key const& lhs, CanonicalTXSet::Key const& rhs)
|
|
{
|
|
if (lhs.account_ < rhs.account_)
|
|
return true;
|
|
|
|
if (lhs.account_ > rhs.account_)
|
|
return false;
|
|
|
|
if (lhs.seqProxy_ < rhs.seqProxy_)
|
|
return true;
|
|
|
|
if (lhs.seqProxy_ > rhs.seqProxy_)
|
|
return false;
|
|
|
|
return lhs.txId_ < rhs.txId_;
|
|
}
|
|
|
|
uint256
|
|
CanonicalTXSet::accountKey(AccountID const& account)
|
|
{
|
|
uint256 ret = beast::zero;
|
|
memcpy(ret.begin(), account.begin(), account.size());
|
|
ret ^= salt_;
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
CanonicalTXSet::insert(std::shared_ptr<STTx const> const& txn)
|
|
{
|
|
map_.insert(
|
|
std::make_pair(
|
|
Key(accountKey(txn->getAccountID(sfAccount)),
|
|
txn->getSeqProxy(),
|
|
txn->getTransactionID()),
|
|
txn));
|
|
}
|
|
|
|
std::shared_ptr<STTx const>
|
|
CanonicalTXSet::popAcctTransaction(std::shared_ptr<STTx const> const& tx)
|
|
{
|
|
// Determining the next viable transaction for an account with Tickets:
|
|
//
|
|
// 1. Prioritize transactions with Sequences over transactions with
|
|
// Tickets.
|
|
//
|
|
// 2. For transactions not using Tickets, look for consecutive Sequence
|
|
// numbers. For transactions using Tickets, don't worry about
|
|
// consecutive Sequence numbers. Tickets can process out of order.
|
|
//
|
|
// 3. After handling all transactions with Sequences, return Tickets
|
|
// with the lowest Ticket ID first.
|
|
std::shared_ptr<STTx const> result;
|
|
uint256 const effectiveAccount{accountKey(tx->getAccountID(sfAccount))};
|
|
|
|
auto const seqProxy = tx->getSeqProxy();
|
|
Key const after(effectiveAccount, seqProxy, beast::zero);
|
|
auto const itrNext{map_.lower_bound(after)};
|
|
if (itrNext != map_.end() && itrNext->first.getAccount() == effectiveAccount &&
|
|
(!itrNext->second->getSeqProxy().isSeq() ||
|
|
itrNext->second->getSeqProxy().value() == seqProxy.value() + 1))
|
|
{
|
|
result = std::move(itrNext->second);
|
|
map_.erase(itrNext);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
} // namespace xrpl
|