3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/consensus/ConsensusParms.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/json/json_writer.h>
9#include <boost/container/flat_map.hpp>
34template <
class Tx,
class NodeId>
38 using Map_t = boost::container::flat_map<NodeId, bool>;
58 [[nodiscard]]
TxID_t const&
93 if (nextCutoff.consensusTime > currentCutoff.consensusTime ||
113 int const support = (
yays_ + (proposing &&
ourVote_ ? 1 : 0)) * 100;
114 int const total =
nays_ +
yays_ + (proposing ? 1 : 0);
120 int const weight = support / total;
130 s <<
"Transaction " <<
id() <<
" is stalled. We have been voting "
132 <<
" rounds. Peers have not changed their votes in " << peersUnchanged
133 <<
" rounds. The transaction has " << weight <<
"% support. ";
134 JLOG(
j_.error()) << s.
str();
135 CLOG(clog) << s.
str();
144 [[nodiscard]] Tx
const&
222template <
class Tx,
class NodeId>
233 JLOG(
j_.debug()) <<
"Peer " << peer <<
" votes YES on " <<
tx_.id();
238 JLOG(
j_.debug()) <<
"Peer " << peer <<
" votes NO on " <<
tx_.id();
244 if (votesYes && !it->second)
246 JLOG(
j_.debug()) <<
"Peer " << peer <<
" now votes YES on " <<
tx_.id();
253 if (!votesYes && it->second)
255 JLOG(
j_.debug()) <<
"Peer " << peer <<
" now votes NO on " <<
tx_.id();
265template <
class Tx,
class NodeId>
269 auto it =
votes_.find(peer);
286template <
class Tx,
class NodeId>
296 bool newPosition =
false;
305 auto const [requiredPct, newState] =
318 newPosition = weight > requiredPct;
330 JLOG(
j_.info()) <<
"No change (" << (
ourVote_ ?
"YES" :
"NO") <<
") on " <<
tx_.id()
331 <<
" : weight " << weight <<
", percent " << percentTime
339 JLOG(
j_.debug()) <<
"We now vote " << (
ourVote_ ?
"YES" :
"NO") <<
" on " <<
tx_.id();
344template <
class Tx,
class NodeId>
359 for (
auto const& [nodeId, vote] :
votes_)
361 ret[
"votes"] = std::move(votes);
A generic endpoint for log messages.
Decorator for streaming out compact json.
ConsensusParms::AvalancheState avalancheState_
std::size_t currentVoteCounter_
void setOurVote(bool o)
Change our vote.
TxID_t const & id() const
The unique id/hash of the disputed transaction.
boost::container::flat_map< NodeID_t, bool > Map_t
json::Value getJson() const
JSON representation of dispute, used for debugging.
void unVote(NodeId const &peer)
Remove a peer's vote.
bool updateVote(int percentTime, bool proposing, ConsensusParms const &p)
Update our vote given progression of consensus.
bool setVote(NodeId const &peer, bool votesYes)
Change a peer's vote.
DisputedTx(Tx tx, bool ourVote, std::size_t numPeers, beast::Journal j)
Constructor.
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?
std::size_t avalancheCounter_
bool getOurVote() const
Our vote on whether the transaction should be included.
@ Object
object value (collection of name/value pairs).
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_string(BaseUInt< Bits, Tag > const &a)
json::Value getJson(LedgerFill const &fill)
Return a new json::Value representing the ledger with given options.
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)
Consensus algorithm parameters.
std::size_t const avMinRounds
Number of rounds before certain actions can happen.
std::size_t const avStalledRounds
Number of rounds before a stuck vote is considered unlikely to change because voting stalled.
std::map< AvalancheState, AvalancheCutoff > const avalancheCutoffs
Map the consensus requirement avalanche state to the amount of time that must pass before moving to t...
std::size_t const minConsensusPct
The percentage threshold above which we can declare consensus.