feat(consensus): default sidecar reconciliation off

Compile out sidecar acquisition and merge plumbing unless xahaud_sidecar_reconciliation is enabled, and move fetch-positive .testnet scenarios into an opt-in suite.

When reconciliation is enabled, gate eager fetches on current trusted root support so first-seen transient roots do not trigger network acquisition. This keeps the recovery path available for measurement without making it the default path.

Verified default OFF with x-format-changed, git diff --check, x-quick-check, cmake configure/build, and ./build/rippled --unittest=ConsensusExtensions. ON path syntax-checked; Claude is assigned the parallel ON build/test review in a separate worktree.
This commit is contained in:
Nicholas Dudfield
2026-06-30 16:10:50 +07:00
parent 67c2c44263
commit d4650441fb
12 changed files with 328 additions and 93 deletions

View File

@@ -39,16 +39,6 @@ tests:
- n3:no_export_sig=true
- n4:no_export_sig=true
# Resilience counterpart to export_degradation: all nodes DO sign, but the
# scenario drops one validator's proposals to n0 after setup. n0 remains above
# quorum from direct proposals, but must reconstruct the missing sidecar leaf
# through the fetch/acquisition path.
- name: export_sidecar_fetch_under_proposal_drop_ce
script: .testnet/scenarios/export/export_fetch_under_proposal_drop.py
network:
rc:
- rng_poll_ms=333
- name: export_without_unl_report
script: .testnet/scenarios/export/export_without_unl_report.py
network:

View File

@@ -0,0 +1,48 @@
# Opt-in suite for the sidecar SHAMap reconciliation path.
#
# These scenarios assert fetch/acquire/merge behavior and require a binary built
# with:
#
# -Dxahaud_sidecar_reconciliation=ON
#
# The normal feature suites default to proposal-carried CE/export material and
# do not run these tests while reconciliation is disabled by default.
defaults:
network:
node_count: 5
launcher: tmux
find_ports: true
slave_delay: 0.2
features:
- ConsensusEntropy
- Export
track_features:
- ConsensusEntropy
- Export
unl_report: true
log_levels:
TxQ: info
Protocol: debug
Peer: debug
LedgerConsensus: debug
ConsensusExtensions: debug
NetworkOPs: info
env:
XAHAU_RESOURCE_PER_PORT: "1"
rc:
- rng_poll_ms=333
tests:
- name: entropy_fetch_recovers_dropped_claims
script: .testnet/scenarios/entropy/fetch_recovers_dropped_claims.py
network:
rc:
- rng_poll_ms=333
- n0:rngrevealdrop=100
- name: export_sidecar_fetch_under_proposal_drop_ce
script: .testnet/scenarios/export/export_fetch_under_proposal_drop.py
network:
rc:
- rng_poll_ms=333

View File

@@ -25,13 +25,6 @@ tests:
- name: steady_state_entropy
script: .testnet/scenarios/entropy/steady_state_entropy.py
- name: entropy_fetch_recovers_dropped_claims
script: .testnet/scenarios/entropy/fetch_recovers_dropped_claims.py
network:
rc:
- rng_poll_ms=333
- n0:rngrevealdrop=100
- name: fallback_without_unl_report
script: .testnet/scenarios/entropy/fallback_without_unl_report.py
network:

View File

@@ -181,6 +181,9 @@ if(xrpld)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
)
if(NOT xahaud_sidecar_reconciliation)
list(FILTER sources EXCLUDE REGEX "/src/xrpld/app/ledger/SidecarSetSF\\.cpp$")
endif()
target_sources(rippled PRIVATE ${sources})
if(tests)

View File

@@ -21,7 +21,7 @@ option(xahaud_runtime_test_config
option(xahaud_sidecar_reconciliation
"Enable consensus-extension sidecar SHAMap fetch/acquire/reconcile path"
ON)
OFF)
option(unity "Creates a build using UNITY support in cmake. This is the default" ON)
if(unity)

View File

@@ -1143,7 +1143,9 @@ struct Export_test : public beast::unit_test::suite
ce.exportSigCollector().addVerifiedSignature(
txHash, valPK, originalSig, applySeq);
auto const agreedHash = ce.buildExportSigSet(applySeq);
BEAST_EXPECT(ce.isSidecarSet(agreedHash));
BEAST_EXPECT(
ce.isSidecarSet(agreedHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
ce.acceptExportSigSet(agreedHash);
ce.setExportSigConvergenceFailed();
@@ -1541,7 +1543,9 @@ struct Export_test : public beast::unit_test::suite
ce.exportSigCollector().addVerifiedSignature(
txHash, valPK, sig, applySeq);
auto const agreedHash = ce.buildExportSigSet(applySeq);
BEAST_EXPECT(ce.isSidecarSet(agreedHash));
BEAST_EXPECT(
ce.isSidecarSet(agreedHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
ce.acceptExportSigSet(agreedHash);
auto const parent = env.app().getLedgerMaster().getClosedLedger();
@@ -1613,7 +1617,9 @@ struct Export_test : public beast::unit_test::suite
ce.exportSigCollector().addVerifiedSignature(
txHash, valPK, sig, applySeq);
auto const agreedHash = ce.buildExportSigSet(applySeq);
BEAST_EXPECT(ce.isSidecarSet(agreedHash));
BEAST_EXPECT(
ce.isSidecarSet(agreedHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
ce.acceptExportSigSet(agreedHash);
ExportResultBuilder::SignatureSnapshot signatures;

View File

@@ -1471,7 +1471,9 @@ class ConsensusExtensions_test : public beast::unit_test::suite
auto const entropySetHash = ce.buildEntropySet(seq);
ce.acceptEntropySet(entropySetHash);
BEAST_EXPECT(ce.isSidecarSet(entropySetHash));
BEAST_EXPECT(
ce.isSidecarSet(entropySetHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
// Once the sidecar gate has accepted a hash, injection is derived from
// that sidecar snapshot. A local failure flag is diagnostic state, not
// an additional selector input.
@@ -2362,7 +2364,9 @@ class ConsensusExtensions_test : public beast::unit_test::suite
ce.exportSigCollector().addVerifiedSignature(
txHash, valPK, originalSig, seq);
auto const exportSigSetHash = ce.buildExportSigSet(seq);
BEAST_EXPECT(ce.isSidecarSet(exportSigSetHash));
BEAST_EXPECT(
ce.isSidecarSet(exportSigSetHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
auto const view = ce.activeValidatorView();
// A locally-built export signature map is not closed-ledger material
@@ -4154,7 +4158,9 @@ class ConsensusExtensions_test : public beast::unit_test::suite
auto const seq = ledger->info().seq + 1;
auto const commitHash = ce.buildCommitSet(seq);
BEAST_EXPECT(ce.isSidecarSet(commitHash));
BEAST_EXPECT(
ce.isSidecarSet(commitHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
ExtendedPosition revealPos{commitPos.txSetHash};
revealPos.myReveal = ce.getEntropySecret();
@@ -4178,7 +4184,9 @@ class ConsensusExtensions_test : public beast::unit_test::suite
BEAST_EXPECT(ce.pendingRevealCount() == 1);
BEAST_EXPECT(ce.hasMinimumReveals());
auto const entropyHash = ce.buildEntropySet(seq);
BEAST_EXPECT(ce.isSidecarSet(entropyHash));
BEAST_EXPECT(
ce.isSidecarSet(entropyHash) ==
ConsensusExtensions::sidecarReconciliationEnabled());
}
public:
@@ -4203,16 +4211,22 @@ public:
testOnPreBuildTier2WithNegativeUNL();
testProposalProofRoundTrip();
testHarvestRngDataReplacementAndRejection();
testExportSidecarBuildFetchAndMerge();
testExportSidecarIgnoresCancelOnlyExports();
testExportSidecarBuildCapsConsensusCandidates();
testExportSidecarRejectsInvalidFetchedEntries();
testExportSidecarRejectsOversizedFetchedSet();
if constexpr (ConsensusExtensions::sidecarReconciliationEnabled())
{
testExportSidecarBuildFetchAndMerge();
testExportSidecarIgnoresCancelOnlyExports();
testExportSidecarBuildCapsConsensusCandidates();
testExportSidecarRejectsInvalidFetchedEntries();
testExportSidecarRejectsOversizedFetchedSet();
}
testExportAgreedSignaturesIgnoreLiveCollectorMutation();
testOnPreBuildPreservesExportDecision();
testRngSidecarBuildFetchAndMerge();
testRngSidecarRejectsOversizedFetchedSet();
testRngSidecarRejectsInvalidFetchedEntries();
if constexpr (ConsensusExtensions::sidecarReconciliationEnabled())
{
testRngSidecarBuildFetchAndMerge();
testRngSidecarRejectsOversizedFetchedSet();
testRngSidecarRejectsInvalidFetchedEntries();
}
testOnPreBuildInjectsStandaloneEntropy();
testOnPreBuildEntropyMismatchKeepsAgreed();
testDiagnosticsJsonAndPositionLogging();

View File

@@ -50,6 +50,7 @@
#include <algorithm>
#include <cstring>
#include <iterator>
#include <limits>
#include <random>
namespace ripple {
@@ -181,6 +182,7 @@ makeSidecarItem(STObject const& sidecar)
return make_shamapitem(itemKey, s.slice());
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
bool
sidecarLeafCountWithin(SHAMap const& map, std::size_t maxLeaves)
{
@@ -196,6 +198,7 @@ sidecarLeafCountWithin(SHAMap const& map, std::size_t maxLeaves)
});
return within;
}
#endif
//@@start active-validator-view-build
ActiveValidatorViewSource
@@ -406,6 +409,117 @@ ConsensusExtensions::entropyGateThreshold() const
return entropyGateThresholdForView(view->size(), view->originalViewSize);
}
void
ConsensusExtensions::recordSidecarRootSupport(
NodeID const& nodeId,
ExtendedPosition const& position)
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (!isUNLReportMember(nodeId))
return;
auto record = [&](auto& roots, std::optional<uint256> const& hash) {
for (auto it = roots.begin(); it != roots.end();)
{
auto current = it++;
current->second.erase(nodeId);
if (current->second.empty())
roots.erase(current);
}
if (hash && *hash != uint256{})
roots[*hash].insert(nodeId);
};
record(sidecarRootSupport_.commitSet, position.commitSetHash);
record(sidecarRootSupport_.entropySet, position.entropySetHash);
record(sidecarRootSupport_.exportSigSet, position.exportSigSetHash);
#else
(void)nodeId;
(void)position;
#endif
}
std::size_t
ConsensusExtensions::sidecarRootSupport(SidecarKind kind, uint256 const& hash)
const
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
auto observedSupport = [&](auto const& roots) -> std::size_t {
auto const it = roots.find(hash);
return it == roots.end() ? 0 : it->second.size();
};
std::size_t support = 0;
auto const localContribution =
localIsActiveValidator() ? std::size_t{1} : std::size_t{0};
switch (kind)
{
case SidecarKind::commitSet:
support = observedSupport(sidecarRootSupport_.commitSet);
if (commitSetMap_ && commitSetMap_->getHash().as_uint256() == hash)
support += localContribution;
break;
case SidecarKind::entropySet:
support = observedSupport(sidecarRootSupport_.entropySet);
if (entropySetMap_ &&
entropySetMap_->getHash().as_uint256() == hash)
support += localContribution;
break;
case SidecarKind::exportSigSet:
support = observedSupport(sidecarRootSupport_.exportSigSet);
if (exportSigSetMap_ &&
exportSigSetMap_->getHash().as_uint256() == hash)
support += localContribution;
break;
}
return support;
#else
(void)kind;
(void)hash;
return 0;
#endif
}
std::size_t
ConsensusExtensions::sidecarFetchSupportThreshold(SidecarKind kind) const
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
auto const threshold = kind == SidecarKind::exportSigSet
? exportSigQuorumThreshold()
: entropyGateThreshold();
return threshold == 0 ? std::numeric_limits<std::size_t>::max() : threshold;
#else
(void)kind;
return std::numeric_limits<std::size_t>::max();
#endif
}
bool
ConsensusExtensions::shouldEagerFetchSidecarSet(
SidecarKind kind,
uint256 const& hash) const
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
auto const support = sidecarRootSupport(kind, hash);
auto const threshold = sidecarFetchSupportThreshold(kind);
if (support >= threshold)
return true;
JLOG(j_.trace()) << "SIDECARFETCH: skip"
<< " kind=" << sidecarKindName(kind)
<< " origin=eagerProposal"
<< " hash=" << hash
<< " reason=root-support-below-threshold"
<< " support=" << support << " threshold=" << threshold;
return false;
#else
(void)kind;
(void)hash;
return false;
#endif
}
std::size_t
ConsensusExtensions::entropyGateThresholdForView(
std::size_t effectiveViewSize,
@@ -1425,6 +1539,7 @@ ConsensusExtensions::clearRngStatePreservingExport()
consensusExportTxns_.clear();
consensusTxSetHash_.reset();
pendingSidecarFetches_.clear();
sidecarRootSupport_ = {};
observedParticipantsHash_.reset();
observedParticipantsCount_ = 0;
observedParticipantsBitmapBin_.clear();
@@ -1555,9 +1670,7 @@ ConsensusExtensions::isActiveValidator(
bool
ConsensusExtensions::isSidecarSet(uint256 const& hash) const
{
if constexpr (!sidecarReconciliationEnabled())
return false;
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (commitSetMap_ && commitSetMap_->getHash().as_uint256() == hash)
return true;
if (entropySetMap_ && entropySetMap_->getHash().as_uint256() == hash)
@@ -1565,6 +1678,10 @@ ConsensusExtensions::isSidecarSet(uint256 const& hash) const
if (exportSigSetMap_ && exportSigSetMap_->getHash().as_uint256() == hash)
return true;
return pendingSidecarFetches_.find(hash) != pendingSidecarFetches_.end();
#else
(void)hash;
return false;
#endif
}
//@@end is-sidecar-set
@@ -1573,14 +1690,7 @@ ConsensusExtensions::isSidecarSet(uint256 const& hash) const
void
ConsensusExtensions::onAcquiredSidecarSet(std::shared_ptr<SHAMap> const& map)
{
if constexpr (!sidecarReconciliationEnabled())
{
JLOG(j_.debug()) << "SIDECARFETCH: acquired set ignored"
<< " reason=reconciliation-disabled"
<< " hash=" << map->getHash().as_uint256();
return;
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
auto const hash = map->getHash().as_uint256();
// Look up the expected kind before erasing.
@@ -1974,6 +2084,11 @@ ConsensusExtensions::onAcquiredSidecarSet(std::shared_ptr<SHAMap> const& map)
<< " pendingBefore=" << pendingBefore
<< " pendingAfter=" << pendingAfter
<< " pendingDelta=" << pendingDelta;
#else
JLOG(j_.debug()) << "SIDECARFETCH: acquired set ignored"
<< " reason=reconciliation-disabled"
<< " hash=" << map->getHash().as_uint256();
#endif
}
//@@end handle-acquired-sidecar
@@ -1983,18 +2098,7 @@ ConsensusExtensions::fetchSidecarSetIfNeeded(
SidecarKind kind,
char const* origin)
{
if constexpr (!sidecarReconciliationEnabled())
{
if (hash && *hash != uint256{})
{
JLOG(j_.trace())
<< "SIDECARFETCH: skip"
<< " kind=" << sidecarKindName(kind) << " origin=" << origin
<< " hash=" << *hash << " reason=reconciliation-disabled";
}
return;
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (!hash)
{
JLOG(j_.trace()) << "SIDECARFETCH: skip"
@@ -2090,6 +2194,15 @@ ConsensusExtensions::fetchSidecarSetIfNeeded(
<< " origin=" << origin << " hash=" << *hash;
onAcquiredSidecarSet(immediate);
}
#else
if (hash && *hash != uint256{})
{
JLOG(j_.trace()) << "SIDECARFETCH: skip"
<< " kind=" << sidecarKindName(kind)
<< " origin=" << origin << " hash=" << *hash
<< " reason=reconciliation-disabled";
}
#endif
}
void
@@ -2097,19 +2210,22 @@ ConsensusExtensions::fetchSidecarsIfNeeded(
ExtendedPosition const& peerPos,
char const* origin)
{
if constexpr (!sidecarReconciliationEnabled())
{
(void)peerPos;
(void)origin;
return;
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
auto const isEager = std::strcmp(origin, "eagerProposal") == 0;
auto fetch = [&](std::optional<uint256> const& hash, SidecarKind kind) {
if (isEager && hash && *hash != uint256{} &&
!shouldEagerFetchSidecarSet(kind, *hash))
return;
fetchSidecarSetIfNeeded(hash, kind, origin);
};
fetchSidecarSetIfNeeded(
peerPos.commitSetHash, SidecarKind::commitSet, origin);
fetchSidecarSetIfNeeded(
peerPos.entropySetHash, SidecarKind::entropySet, origin);
fetchSidecarSetIfNeeded(
peerPos.exportSigSetHash, SidecarKind::exportSigSet, origin);
fetch(peerPos.commitSetHash, SidecarKind::commitSet);
fetch(peerPos.entropySetHash, SidecarKind::entropySet);
fetch(peerPos.exportSigSetHash, SidecarKind::exportSigSet);
#else
(void)peerPos;
(void)origin;
#endif
}
void
@@ -2850,6 +2966,8 @@ ConsensusExtensions::onTrustedPeerProposal(
return;
}
recordSidecarRootSupport(nodeId, position);
harvestRngData(
nodeId,
publicKey,

View File

@@ -28,7 +28,7 @@
namespace ripple {
#ifndef XAHAUD_ENABLE_SIDECAR_RECONCILIATION
#define XAHAUD_ENABLE_SIDECAR_RECONCILIATION 1
#define XAHAUD_ENABLE_SIDECAR_RECONCILIATION 0
#endif
class Application;
@@ -127,6 +127,17 @@ private:
// content-sniffing and logs can attribute eager vs gate-triggered fetches.
hash_map<uint256, PendingSidecarFetch> pendingSidecarFetches_;
struct SidecarRootSupport
{
hash_map<uint256, hash_set<NodeID>> commitSet;
hash_map<uint256, hash_set<NodeID>> entropySet;
hash_map<uint256, hash_set<NodeID>> exportSigSet;
};
// Per-round support for sidecar roots observed in trusted proposals. Eager
// acquisition uses this to avoid fetching first-seen transient roots.
SidecarRootSupport sidecarRootSupport_;
// Parent-ledger validator view used by RNG and Export quorum logic.
ActiveValidatorViewPtr activeValidatorView_ =
std::make_shared<ActiveValidatorView const>();
@@ -175,6 +186,20 @@ private:
char const* sourceTag,
RngProofCachePolicy proofCachePolicy);
void
recordSidecarRootSupport(
NodeID const& nodeId,
ExtendedPosition const& position);
std::size_t
sidecarRootSupport(SidecarKind kind, uint256 const& hash) const;
std::size_t
sidecarFetchSupportThreshold(SidecarKind kind) const;
bool
shouldEagerFetchSidecarSet(SidecarKind kind, uint256 const& hash) const;
// Commit proofs keyed by NodeID. Only seq=0 proofs are cached because the
// commit sidecar hash must be deterministic across all nodes.
hash_map<NodeID, ProposalProof> commitProofs_;

View File

@@ -1032,29 +1032,21 @@ RCLConsensus::phase() const
bool
RCLConsensus::isExtensionSet(uint256 const& hash) const
{
if constexpr (!ConsensusExtensions::sidecarReconciliationEnabled())
{
(void)hash;
return false;
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
std::lock_guard _{mutex_};
if (consensus_->phase() == ConsensusPhase::accepted)
return false;
return adaptor_.ce().isSidecarSet(hash);
#else
(void)hash;
return false;
#endif
}
void
RCLConsensus::gotExtensionSet(std::shared_ptr<SHAMap> const& map)
{
if constexpr (!ConsensusExtensions::sidecarReconciliationEnabled())
{
JLOG(j_.debug()) << "Ignoring acquired sidecar set "
<< map->getHash().as_uint256()
<< " reason=reconciliation-disabled";
return;
}
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
std::lock_guard _{mutex_};
// Accept builds run without the consensus mutex and clear extension
// working state. Late sidecar fetches belong to the previous establish
@@ -1066,6 +1058,11 @@ RCLConsensus::gotExtensionSet(std::shared_ptr<SHAMap> const& map)
return;
}
adaptor_.ce().onAcquiredSidecarSet(map);
#else
JLOG(j_.debug()) << "Ignoring acquired sidecar set "
<< map->getHash().as_uint256()
<< " reason=reconciliation-disabled";
#endif
}
bool

View File

@@ -20,16 +20,24 @@
#include <xrpld/app/ledger/ConsensusTransSetSF.h>
#include <xrpld/app/ledger/InboundLedgers.h>
#include <xrpld/app/ledger/InboundTransactions.h>
#include <xrpld/app/ledger/SidecarSetSF.h>
#include <xrpld/app/ledger/detail/TransactionAcquire.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/app/misc/NetworkOPs.h>
#include <xrpld/overlay/Overlay.h>
#include <xrpld/overlay/detail/ProtocolMessage.h>
#include <xrpld/shamap/SHAMapSyncFilter.h>
#include <xrpl/basics/contract.h>
#include <memory>
#ifndef XAHAUD_ENABLE_SIDECAR_RECONCILIATION
#define XAHAUD_ENABLE_SIDECAR_RECONCILIATION 0
#endif
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
#include <xrpld/app/ledger/SidecarSetSF.h>
#endif
namespace ripple {
using namespace std::chrono_literals;
@@ -47,14 +55,47 @@ namespace {
std::unique_ptr<SHAMapSyncFilter>
makeSyncFilter(InboundSetKind kind, Application& app)
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
// Sidecars deliberately reuse candidate tx-set acquisition; the filter only
// changes leaf handling so sidecar STObjects are cached, not submitted.
if (kind == InboundSetKind::sidecar)
return std::make_unique<SidecarSetSF>(app.getTempNodeCache());
#else
if (kind == InboundSetKind::sidecar)
LogicError("Sidecar acquisition requested while disabled");
#endif
return std::make_unique<ConsensusTransSetSF>(app, app.getTempNodeCache());
}
SHAMapType
acquireMapType(InboundSetKind kind)
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (kind == InboundSetKind::sidecar)
return SHAMapType::SIDECAR;
#else
if (kind == InboundSetKind::sidecar)
LogicError("Sidecar SHAMap acquisition requested while disabled");
#endif
return SHAMapType::TRANSACTION;
}
char const*
acquireSetKindName(InboundSetKind kind)
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (kind == InboundSetKind::sidecar)
return "sidecar";
#else
if (kind == InboundSetKind::sidecar)
return "sidecar-disabled";
#endif
return "TX";
}
} // namespace
TransactionAcquire::TransactionAcquire(
@@ -72,13 +113,10 @@ TransactionAcquire::TransactionAcquire(
, mPeerSet(std::move(peerSet))
, mSetKind(kind)
{
// Keep sidecar fetch on the same content-addressed SHAMap path as tx sets:
// normal reply limits, peer scoring, charging, and timeout behavior apply.
// Candidate set acquisition is content-addressed; normal reply limits, peer
// scoring, charging, and timeout behavior apply.
mMap = std::make_shared<SHAMap>(
kind == InboundSetKind::sidecar ? SHAMapType::SIDECAR
: SHAMapType::TRANSACTION,
hash,
app_.getNodeFamily());
acquireMapType(kind), hash, app_.getNodeFamily());
mMap->setUnbacked();
}
@@ -94,9 +132,7 @@ TransactionAcquire::done()
else
{
JLOG(journal_.debug())
<< "Acquired "
<< (mSetKind == InboundSetKind::sidecar ? "sidecar" : "TX")
<< " set " << hash_;
<< "Acquired " << acquireSetKindName(mSetKind) << " set " << hash_;
mMap->setImmutable();
uint256 const& hash(hash_);

View File

@@ -1990,6 +1990,7 @@ NetworkOPsImp::mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire)
auto const hash = map->getHash().as_uint256();
if (map->mapType() == SHAMapType::SIDECAR)
{
#if XAHAUD_ENABLE_SIDECAR_RECONCILIATION
if (mConsensus.isExtensionSet(hash))
{
// Extension sidecar set (commitSet, entropySet, or
@@ -2005,6 +2006,10 @@ NetworkOPsImp::mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire)
JLOG(m_journal.debug())
<< "Ignoring stale acquired sidecar set " << hash;
}
#else
JLOG(m_journal.debug()) << "Ignoring acquired sidecar set " << hash
<< " reason=reconciliation-disabled";
#endif
return;
}
mConsensus.gotTxSet(app_.timeKeeper().closeTime(), RCLTxSet{map});