mirror of
https://github.com/Xahau/xahaud.git
synced 2026-08-26 09:40:52 +00:00
Compare commits
5 Commits
reduce-mag
...
fail-fast-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e6cda4d64 | ||
|
|
c146f15247 | ||
|
|
fb5081d1f4 | ||
|
|
d4bec012a2 | ||
|
|
f7187ba94f |
@@ -95,16 +95,8 @@ if [[ "$4" == "" ]]; then
|
||||
echo "Non GH, local building, no Action runner magic"
|
||||
else
|
||||
# GH Action, runner
|
||||
if [[ "$(git rev-parse --abbrev-ref HEAD)" == "release" ]]; then
|
||||
echo "building on the release branch... placing it in builds/candidate"
|
||||
mkdir /data/builds/candidate
|
||||
cp /io/release-build/xahaud /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
else
|
||||
echo "building non-release branch, placing it in builds root"
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
fi
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
echo "Published build to: http://build.xahau.tech/"
|
||||
echo $(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
fi
|
||||
|
||||
@@ -311,12 +311,28 @@ LedgerMaster::setValidLedger(std::shared_ptr<Ledger const> const& l)
|
||||
if (auto const first =
|
||||
app_.getAmendmentTable().firstUnsupportedExpected())
|
||||
{
|
||||
JLOG(m_journal.error()) << "One or more unsupported amendments "
|
||||
"reached majority. Upgrade before "
|
||||
<< to_string(*first)
|
||||
<< " to prevent your server from "
|
||||
"becoming amendment blocked.";
|
||||
app_.getOPs().setAmendmentWarned();
|
||||
using namespace std::chrono_literals;
|
||||
auto const now = app_.timeKeeper().closeTime();
|
||||
if (*first > now && (*first - now) <= 1min)
|
||||
{
|
||||
// Shut down just before the amendment activates to
|
||||
// avoid processing ledgers with unknown fields.
|
||||
JLOG(m_journal.error())
|
||||
<< "Unsupported amendment activating imminently "
|
||||
"at "
|
||||
<< to_string(*first) << ". Shutting down.";
|
||||
app_.getOPs().setAmendmentBlocked();
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(m_journal.error())
|
||||
<< "One or more unsupported amendments "
|
||||
"reached majority. Upgrade before "
|
||||
<< to_string(*first)
|
||||
<< " to prevent your server from "
|
||||
"becoming amendment blocked.";
|
||||
app_.getOPs().setAmendmentWarned();
|
||||
}
|
||||
}
|
||||
else
|
||||
app_.getOPs().clearAmendmentWarned();
|
||||
|
||||
@@ -1634,6 +1634,16 @@ NetworkOPsImp::setAmendmentBlocked()
|
||||
{
|
||||
amendmentBlocked_ = true;
|
||||
setMode(OperatingMode::CONNECTED);
|
||||
if (!app_.config().standalone())
|
||||
{
|
||||
JLOG(m_journal.fatal())
|
||||
<< "One or more unsupported amendments activated. "
|
||||
"Shutting down. Upgrade the server to remain "
|
||||
"compatible with the network.";
|
||||
app_.signalStop(
|
||||
"One or more unsupported amendments activated. "
|
||||
"Server must be upgraded to remain compatible with the network.");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
@@ -1789,8 +1799,23 @@ NetworkOPsImp::switchLastClosedLedger(
|
||||
|
||||
clearNeedNetworkLedger();
|
||||
|
||||
// Update fee computations.
|
||||
app_.getTxQ().processClosedLedger(app_, *newLCL, true);
|
||||
// Update fee computations. May throw if the ledger contains
|
||||
// transactions with fields unknown to this binary (e.g. after an
|
||||
// unsupported amendment activates). Catch to allow graceful shutdown.
|
||||
//@@start process-closed-ledger-catch
|
||||
try
|
||||
{
|
||||
app_.getTxQ().processClosedLedger(app_, *newLCL, true);
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
{
|
||||
if (!amendmentBlocked_)
|
||||
throw;
|
||||
JLOG(m_journal.error())
|
||||
<< "Failed to process closed ledger: " << e.what();
|
||||
return;
|
||||
}
|
||||
//@@end process-closed-ledger-catch
|
||||
|
||||
// Caller must own master lock
|
||||
{
|
||||
@@ -2449,7 +2474,7 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
|
||||
"may be incorrectly configured or some [validator_list_sites] "
|
||||
"may be unreachable.";
|
||||
}
|
||||
if (admin && isAmendmentWarned())
|
||||
if (isAmendmentWarned())
|
||||
{
|
||||
Json::Value& w = warnings.append(Json::objectValue);
|
||||
w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
|
||||
@@ -2893,6 +2918,7 @@ NetworkOPsImp::pubLedger(std::shared_ptr<ReadView const> const& lpAccepted)
|
||||
// Ledgers are published only when they acquire sufficient validations
|
||||
// Holes are filled across connection loss or other catastrophe
|
||||
|
||||
//@@start pubLedger-accepted-ledger-construction
|
||||
std::shared_ptr<AcceptedLedger> alpAccepted =
|
||||
app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
|
||||
if (!alpAccepted)
|
||||
@@ -2901,6 +2927,7 @@ NetworkOPsImp::pubLedger(std::shared_ptr<ReadView const> const& lpAccepted)
|
||||
app_.getAcceptedLedgerCache().canonicalize_replace_client(
|
||||
lpAccepted->info().hash, alpAccepted);
|
||||
}
|
||||
//@@end pubLedger-accepted-ledger-construction
|
||||
|
||||
XRPL_ASSERT(
|
||||
alpAccepted->getLedger().get() == lpAccepted.get(),
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/AmendmentTable.h>
|
||||
#include <xrpld/app/misc/NetworkOPs.h>
|
||||
#include <xrpld/rpc/detail/TransactionSign.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/RPCErr.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
@@ -31,6 +35,14 @@
|
||||
#include <magic_enum.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#define MAGIC_ENUM(x, _min, _max) \
|
||||
template <> \
|
||||
struct magic_enum::customize::enum_range<x> \
|
||||
{ \
|
||||
static constexpr int min = _min; \
|
||||
static constexpr int max = _max; \
|
||||
};
|
||||
|
||||
#define MAGIC_ENUM_16(x) \
|
||||
template <> \
|
||||
struct magic_enum::customize::enum_range<x> \
|
||||
@@ -46,6 +58,15 @@
|
||||
static constexpr bool is_flags = true; \
|
||||
};
|
||||
|
||||
MAGIC_ENUM(ripple::SerializedTypeID, -2, 10004);
|
||||
MAGIC_ENUM(ripple::LedgerEntryType, 0, 255);
|
||||
MAGIC_ENUM(ripple::TELcodes, -399, 300);
|
||||
MAGIC_ENUM(ripple::TEMcodes, -299, -200);
|
||||
MAGIC_ENUM(ripple::TEFcodes, -199, -100);
|
||||
MAGIC_ENUM(ripple::TERcodes, -99, -1);
|
||||
MAGIC_ENUM(ripple::TEScodes, 0, 1);
|
||||
MAGIC_ENUM(ripple::TECcodes, 100, 255);
|
||||
MAGIC_ENUM_16(ripple::TxType);
|
||||
MAGIC_ENUM_FLAG(ripple::UniversalFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::AccountSetFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::OfferCreateFlags);
|
||||
@@ -171,19 +192,24 @@ private:
|
||||
|
||||
ret[jss::TYPES]["Done"] = -1;
|
||||
std::map<int32_t, std::string> type_map{{-1, "Done"}};
|
||||
for (auto const& [rawName, typeValue] : sTypeMap)
|
||||
for (auto const& entry : magic_enum::enum_entries<SerializedTypeID>())
|
||||
{
|
||||
std::string typeName =
|
||||
translate(std::string(rawName).substr(4) /* remove STI_ */);
|
||||
ret[jss::TYPES][typeName] = typeValue;
|
||||
type_map[typeValue] = typeName;
|
||||
const auto name = entry.second;
|
||||
std::string type_name =
|
||||
translate(name.data() + 4 /* remove STI_ */);
|
||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||
ret[jss::TYPES][type_name] = type_value;
|
||||
type_map[type_value] = type_name;
|
||||
}
|
||||
|
||||
ret[jss::LEDGER_ENTRY_TYPES] = Json::objectValue;
|
||||
ret[jss::LEDGER_ENTRY_TYPES][jss::Invalid] = -1;
|
||||
for (auto const& f : LedgerFormats::getInstance())
|
||||
for (auto const& entry : magic_enum::enum_entries<LedgerEntryType>())
|
||||
{
|
||||
ret[jss::LEDGER_ENTRY_TYPES][f.getName()] = f.getType();
|
||||
const auto name = entry.second;
|
||||
std::string type_name = translate(name.data() + 2 /* remove lt_ */);
|
||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||
ret[jss::LEDGER_ENTRY_TYPES][type_name] = type_value;
|
||||
}
|
||||
|
||||
ret[jss::FIELDS] = Json::arrayValue;
|
||||
@@ -300,16 +326,71 @@ private:
|
||||
}
|
||||
|
||||
ret[jss::TRANSACTION_RESULTS] = Json::objectValue;
|
||||
for (auto const& [code, terInfo] : transResults())
|
||||
for (auto const& entry : magic_enum::enum_entries<TELcodes>())
|
||||
{
|
||||
ret[jss::TRANSACTION_RESULTS][terInfo.first] = code;
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
for (auto const& entry : magic_enum::enum_entries<TEMcodes>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
for (auto const& entry : magic_enum::enum_entries<TEFcodes>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
for (auto const& entry : magic_enum::enum_entries<TERcodes>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
for (auto const& entry : magic_enum::enum_entries<TEScodes>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
for (auto const& entry : magic_enum::enum_entries<TECcodes>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||
static_cast<int32_t>(entry.first);
|
||||
}
|
||||
|
||||
auto const translate_tt = [](std::string inp) -> std::string {
|
||||
if (inp == "Amendment")
|
||||
return "EnableAmendment";
|
||||
if (inp == "Fee")
|
||||
return "SetFee";
|
||||
if (inp == "PaychanClaim")
|
||||
return "PaymentChannelClaim";
|
||||
if (inp == "PaychanCreate")
|
||||
return "PaymentChannelCreate";
|
||||
if (inp == "PaychanFund")
|
||||
return "PaymentChannelFund";
|
||||
if (inp == "RegularKeySet")
|
||||
return "SetRegularKey";
|
||||
if (inp == "HookSet")
|
||||
return "SetHook";
|
||||
if (inp == "RemarksSet")
|
||||
return "SetRemarks";
|
||||
return inp;
|
||||
};
|
||||
|
||||
ret[jss::TRANSACTION_TYPES] = Json::objectValue;
|
||||
ret[jss::TRANSACTION_TYPES][jss::Invalid] = -1;
|
||||
for (auto const& f : TxFormats::getInstance())
|
||||
for (auto const& entry : magic_enum::enum_entries<TxType>())
|
||||
{
|
||||
ret[jss::TRANSACTION_TYPES][f.getName()] = f.getType();
|
||||
const auto name = entry.second;
|
||||
std::string type_name = translate_tt(translate(name.data() + 2));
|
||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||
ret[jss::TRANSACTION_TYPES][type_name] = type_value;
|
||||
}
|
||||
|
||||
// Transaction Flags:
|
||||
|
||||
Reference in New Issue
Block a user