mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-04 11:55:51 +00:00
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)];
|
||||
|
||||
@@ -57,8 +57,7 @@ TEST_F(ETLStateTest, NetworkIdValid)
|
||||
EXPECT_CALL(source, forwardToRippled).WillOnce(Return(json.as_object()));
|
||||
auto const state = etl::ETLState::fetchETLStateFromSource(source);
|
||||
ASSERT_TRUE(state.has_value());
|
||||
ASSERT_TRUE(state->networkID.has_value());
|
||||
EXPECT_EQ(state->networkID.value(), 12);
|
||||
EXPECT_EQ(state->networkID, 12);
|
||||
}
|
||||
|
||||
TEST_F(ETLStateTest, NetworkIdInvalid)
|
||||
@@ -75,7 +74,7 @@ TEST_F(ETLStateTest, NetworkIdInvalid)
|
||||
EXPECT_CALL(source, forwardToRippled).WillOnce(Return(json.as_object()));
|
||||
auto const state = etl::ETLState::fetchETLStateFromSource(source);
|
||||
ASSERT_TRUE(state.has_value());
|
||||
EXPECT_FALSE(state->networkID.has_value());
|
||||
EXPECT_NE(state->networkID, 12);
|
||||
}
|
||||
|
||||
TEST_F(ETLStateTest, ResponseHasError)
|
||||
|
||||
@@ -67,6 +67,7 @@ TEST(RPCErrorsTest, StatusAsBool)
|
||||
RippledError::rpcUNKNOWN_COMMAND,
|
||||
RippledError::rpcTOO_BUSY,
|
||||
RippledError::rpcNO_NETWORK,
|
||||
RippledError::rpcWRONG_NETWORK,
|
||||
RippledError::rpcACT_MALFORMED,
|
||||
RippledError::rpcBAD_MARKET,
|
||||
ClioError::RpcMalformedCurrency,
|
||||
|
||||
@@ -71,6 +71,7 @@ constexpr auto kDEFAULT_OUT1 = R"({
|
||||
"TakerPays": "300",
|
||||
"TransactionType": "OfferCreate",
|
||||
"hash": "2E2FBAAFF767227FE4381C4BE9855986A6B9F96C62F6E443731AB36F7BBB8A08",
|
||||
"ctid": "C000006400640000",
|
||||
"meta": {
|
||||
"AffectedNodes": [
|
||||
{
|
||||
@@ -119,8 +120,10 @@ constexpr auto kDEFAULT_OUT2 = R"({
|
||||
"TransactionIndex": 100,
|
||||
"TransactionResult": "tesSUCCESS"
|
||||
},
|
||||
"ctid": "C000006400640000",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"ctid": "C000006400640000",
|
||||
"date": 123456,
|
||||
"Fee": "2",
|
||||
"ledger_index": 100,
|
||||
@@ -492,7 +495,8 @@ TEST_F(RPCTxTest, ReturnBinary)
|
||||
"date": 123456,
|
||||
"ledger_index": 100,
|
||||
"inLedger": 100,
|
||||
"validated": true
|
||||
"validated": true,
|
||||
"ctid": "C000006400640000"
|
||||
})";
|
||||
|
||||
TransactionAndMetadata tx;
|
||||
@@ -578,6 +582,7 @@ TEST_F(RPCTxTest, MintNFT)
|
||||
"SigningPubKey": "74657374",
|
||||
"TransactionType": "NFTokenMint",
|
||||
"hash": "C74463F49CFDCBEF3E9902672719918CDE5042DC7E7660BEBD1D1105C4B6DFF4",
|
||||
"ctid": "C000006400000000",
|
||||
"meta": {{
|
||||
"AffectedNodes": [
|
||||
{{
|
||||
@@ -829,6 +834,7 @@ TEST_F(RPCTxTest, CTIDNotMatch)
|
||||
ASSERT_FALSE(output);
|
||||
|
||||
auto const err = rpc::makeError(output.result.error());
|
||||
// TODO: https://github.com/XRPLF/clio/issues/2002
|
||||
EXPECT_EQ(err.at("error_code").as_uint64(), 4);
|
||||
EXPECT_EQ(
|
||||
err.at("error_message").as_string(),
|
||||
|
||||
Reference in New Issue
Block a user