fix: CTID issue (#2001)

fixes #1998
This commit is contained in:
Peter Chen
2025-04-16 11:55:12 -07:00
committed by GitHub
parent 4a5fee7548
commit 89eb962d85
8 changed files with 35 additions and 30 deletions

View File

@@ -40,7 +40,7 @@ tag_invoke(boost::json::value_to_tag<ETLState>, boost::json::value const& jv)
if (jsonObject.contains(JS(result)) && jsonObject.at(JS(result)).as_object().contains(JS(info))) {
auto const rippledInfo = jsonObject.at(JS(result)).as_object().at(JS(info)).as_object();
if (rippledInfo.contains(JS(network_id)))
state.networkID.emplace(boost::json::value_to<int64_t>(rippledInfo.at(JS(network_id))));
state.networkID = boost::json::value_to<int64_t>(rippledInfo.at(JS(network_id)));
}
return state;

View File

@@ -38,7 +38,12 @@ namespace etl {
* @brief This class is responsible for fetching and storing the state of the ETL information, such as the network id
*/
struct ETLState {
std::optional<uint32_t> networkID;
/*
* NOTE: Rippled NetworkID: Mainnet = 0; Testnet = 1; Devnet = 2
* However, if rippled is running on neither of these (ie. standalone mode) rippled will default to 0, but
* is not included in the stateOpt response. Must manually add it here.
*/
uint32_t networkID{0};
/**
* @brief Fetch the ETL state from the rippled server

View File

@@ -142,12 +142,11 @@ LoadBalancer::LoadBalancer(
if (!stateOpt) {
LOG(log_.warn()) << "Failed to fetch ETL state from source = " << source->toString()
<< " Please check the configuration and network";
} else if (etlState_ && etlState_->networkID && stateOpt->networkID &&
etlState_->networkID != stateOpt->networkID) {
} else if (etlState_ && etlState_->networkID != stateOpt->networkID) {
checkOnETLFailure(fmt::format(
"ETL sources must be on the same network. Source network id = {} does not match others network id = {}",
*(stateOpt->networkID),
*(etlState_->networkID)
stateOpt->networkID,
etlState_->networkID
));
} else {
etlState_ = stateOpt;

View File

@@ -142,12 +142,11 @@ LoadBalancer::LoadBalancer(
if (!stateOpt) {
LOG(log_.warn()) << "Failed to fetch ETL state from source = " << source->toString()
<< " Please check the configuration and network";
} else if (etlState_ && etlState_->networkID && stateOpt->networkID &&
etlState_->networkID != stateOpt->networkID) {
} else if (etlState_ && etlState_->networkID != stateOpt->networkID) {
checkOnETLFailure(fmt::format(
"ETL sources must be on the same network. Source network id = {} does not match others network id = {}",
*(stateOpt->networkID),
*(etlState_->networkID)
stateOpt->networkID,
etlState_->networkID
));
} else {
etlState_ = stateOpt;

View File

@@ -21,7 +21,6 @@
#include "data/BackendInterface.hpp"
#include "data/Types.hpp"
#include "etl/ETLService.hpp"
#include "etlng/ETLServiceInterface.hpp"
#include "rpc/Errors.hpp"
#include "rpc/JS.hpp"
@@ -39,6 +38,7 @@
#include <boost/json/value.hpp>
#include <boost/json/value_to.hpp>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/LedgerHeader.h>
@@ -214,17 +214,15 @@ public:
// input.transaction might be not available, get hash via tx object
if (txn.contains(JS(hash)))
output.hash = txn.at(JS(hash)).as_string();
}
// append ctid here to mimic rippled 1.12 behavior: return ctid even binary=true
// rippled will change it in the future, ctid should be part of tx json which not available in binary
// mode
auto const txnIdx = boost::json::value_to<uint64_t>(meta.at("TransactionIndex"));
if (txnIdx <= 0xFFFFU && dbResponse->ledgerSequence < 0x0FFF'FFFFUL && currentNetId &&
*currentNetId <= 0xFFFFU) {
output.ctid = rpc::encodeCTID(
dbResponse->ledgerSequence, static_cast<uint16_t>(txnIdx), static_cast<uint16_t>(*currentNetId)
);
}
// append ctid here to mimic rippled behavior
auto const txnIdx = boost::json::value_to<uint64_t>(meta.at("TransactionIndex"));
if (txnIdx <= 0xFFFFU && dbResponse->ledgerSequence < 0x0FFF'FFFFUL && currentNetId &&
*currentNetId <= 0xFFFFU) {
output.ctid = rpc::encodeCTID(
dbResponse->ledgerSequence, static_cast<uint16_t>(txnIdx), static_cast<uint16_t>(*currentNetId)
);
}
output.date = dbResponse->date;
@@ -281,12 +279,10 @@ private:
if (output.tx) {
obj[JS(tx_json)] = *output.tx;
obj[JS(tx_json)].as_object()[JS(date)] = output.date;
if (output.ctid)
obj[JS(tx_json)].as_object()[JS(ctid)] = *output.ctid;
obj[JS(tx_json)].as_object()[JS(ledger_index)] = output.ledgerIndex;
// move ctid from tx_json to root
if (obj[JS(tx_json)].as_object().contains(JS(ctid))) {
obj[JS(ctid)] = obj[JS(tx_json)].as_object()[JS(ctid)];
obj[JS(tx_json)].as_object().erase(JS(ctid));
}
// move hash from tx_json to root
if (obj[JS(tx_json)].as_object().contains(JS(hash))) {
obj[JS(hash)] = obj[JS(tx_json)].as_object()[JS(hash)];