1#ifndef XRPL_APP_CONSENSUS_IMPL_DISPUTEDTX_H_INCLUDED 
    2#define XRPL_APP_CONSENSUS_IMPL_DISPUTEDTX_H_INCLUDED 
    4#include <xrpld/consensus/ConsensusParms.h> 
    6#include <xrpl/basics/Log.h> 
    7#include <xrpl/beast/utility/Journal.h> 
    8#include <xrpl/json/json_writer.h> 
   10#include <boost/container/flat_map.hpp> 
   28template <
class Tx_t, 
class NodeID_t>
 
   32    using Map_t = boost::container::flat_map<NodeID_t, bool>;
 
   84        if (nextCutoff.consensusTime > currentCutoff.consensusTime ||
 
  109        int const weight = support / total;
 
  120            s << 
"Transaction " << 
ID() << 
" is stalled. We have been voting " 
  122              << 
" rounds. Peers have not changed their votes in " 
  123              << peersUnchanged << 
" rounds. The transaction has " << weight
 
  126            CLOG(clog) << s.
str();
 
 
  155    setVote(NodeID_t 
const& peer, 
bool votesYes);
 
  162    unVote(NodeID_t 
const& peer);
 
 
  198template <
class Tx_t, 
class NodeID_t>
 
  202    auto const [it, inserted] = votes_.insert(
std::make_pair(peer, votesYes));
 
  209            JLOG(j_.
debug()) << 
"Peer " << peer << 
" votes YES on " << tx_.id();
 
  214            JLOG(j_.
debug()) << 
"Peer " << peer << 
" votes NO on " << tx_.id();
 
  220    else if (votesYes && !it->second)
 
  222        JLOG(j_.
debug()) << 
"Peer " << peer << 
" now votes YES on " << tx_.id();
 
  229    else if (!votesYes && it->second)
 
  231        JLOG(j_.
debug()) << 
"Peer " << peer << 
" now votes NO on " << tx_.id();
 
 
  241template <
class Tx_t, 
class NodeID_t>
 
  245    auto it = votes_.find(peer);
 
  247    if (it != votes_.end())
 
 
  258template <
class Tx_t, 
class NodeID_t>
 
  265    if (ourVote_ && (nays_ == 0))
 
  268    if (!ourVote_ && (yays_ == 0))
 
  281        p, avalancheState_, percentTime, ++avalancheCounter_, p.
avMIN_ROUNDS);
 
  284        avalancheState_ = *newState;
 
  285        avalancheCounter_ = 0;
 
  291        weight = (yays_ * 100 + (ourVote_ ? 100 : 0)) / (nays_ + yays_ + 1);
 
  293        newPosition = weight > requiredPct;
 
  299        newPosition = yays_ > nays_;
 
  302    if (newPosition == ourVote_)
 
  304        ++currentVoteCounter_;
 
  305        JLOG(j_.
info()) << 
"No change (" << (ourVote_ ? 
"YES" : 
"NO") << 
") on " 
  306                        << tx_.id() << 
" : weight " << weight << 
", percent " 
  308                        << 
", round(s) with this vote: " << currentVoteCounter_;
 
  313    currentVoteCounter_ = 0;
 
  314    ourVote_ = newPosition;
 
  315    JLOG(j_.
debug()) << 
"We now vote " << (ourVote_ ? 
"YES" : 
"NO") << 
" on " 
 
  321template <
class Tx_t, 
class NodeID_t>
 
  331    ret[
"our_vote"] = ourVote_;
 
  336        for (
auto const& [nodeId, vote] : votes_)
 
  338        ret[
"votes"] = std::move(votesj);
 
 
Decorator for streaming out compact json.
 
A generic endpoint for log messages.
 
A transaction discovered to be in dispute during consensus.
 
std::size_t avalancheCounter_
How long we have been in the current acceptance phase.
 
std::size_t currentVoteCounter_
The number of rounds we've gone without changing our vote.
 
Json::Value getJson() const
JSON representation of dispute, used for debugging.
 
bool updateVote(int percentTime, bool proposing, ConsensusParms const &p)
Update our vote given progression of consensus.
 
boost::container::flat_map< NodeID_t, bool > Map_t
 
bool setVote(NodeID_t const &peer, bool votesYes)
Change a peer's vote.
 
ConsensusParms::AvalancheState avalancheState_
Which minimum acceptance percentage phase we are currently in.
 
Tx_t const & tx() const
The disputed transaction.
 
bool stalled(ConsensusParms const &p, bool proposing, int peersUnchanged, beast::Journal j, std::unique_ptr< std::stringstream > const &clog) const
Are we and our peers "stalled" where we probably won't change our vote?
 
DisputedTx(Tx_t const &tx, bool ourVote, std::size_t numPeers, beast::Journal j)
Constructor.
 
bool getOurVote() const
Our vote on whether the transaction should be included.
 
void setOurVote(bool o)
Change our vote.
 
TxID_t const & ID() const
The unique id/hash of the disputed transaction.
 
void unVote(NodeID_t const &peer)
Remove a peer's vote.
 
@ objectValue
object value (collection of name/value pairs).
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
std::pair< std::size_t, std::optional< ConsensusParms::AvalancheState > > getNeededWeight(ConsensusParms const &p, ConsensusParms::AvalancheState currentState, int percentTime, std::size_t currentRounds, std::size_t minimumRounds)
 
@ proposing
We are normal participant in consensus and propose our position.
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
 
Consensus algorithm parameters.
 
std::size_t const avSTALLED_ROUNDS
Number of rounds before a stuck vote is considered unlikely to change because voting stalled.
 
std::size_t const avMIN_ROUNDS
Number of rounds before certain actions can happen.
 
std::size_t const minCONSENSUS_PCT
The percentage threshold above which we can declare consensus.
 
std::map< AvalancheState, AvalancheCutoff > const avalancheCutoffs
Map the consensus requirement avalanche state to the amount of time that must pass before moving to t...