@@ -328,8 +328,23 @@ HerderImpl::processExternalized(uint64 slotIndex, StellarValue const& value,
328328 slotIndex, hexAbbrev (value.txSetHash ));
329329 }
330330
331- TxSetXDRFrameConstPtr externalizedSet =
332- mPendingEnvelopes .getTxSet (value.txSetHash );
331+ auto result = mPendingEnvelopes .getTxSet (value.txSetHash );
332+ TxSetXDRFrameConstPtr externalizedSet;
333+ if (std::holds_alternative<EmptyTxSet>(result))
334+ {
335+ #ifdef CAP_0083
336+ auto const & ov = value.ext .proposedValue ();
337+ externalizedSet = TxSetXDRFrame::makeEmpty (ov.previousLedgerHash ,
338+ ov.previousLedgerVersion );
339+ #else
340+ releaseAssert (false );
341+ #endif // CAP_0083
342+ }
343+ else
344+ {
345+ externalizedSet = std::get<TxSetXDRFrameConstPtr>(result);
346+ }
347+ releaseAssert (externalizedSet != nullptr );
333348
334349 {
335350 ZoneNamedN (updateSCPHistoryZone, " update SCP history" , true );
@@ -937,7 +952,7 @@ HerderImpl::recvSCPEnvelope(SCPEnvelope const& envelope)
937952
938953Herder::EnvelopeStatus
939954HerderImpl::recvSCPEnvelope (SCPEnvelope const & envelope,
940- const SCPQuorumSet& qset,
955+ SCPQuorumSet const & qset,
941956 TxSetXDRFrameConstPtr txset)
942957{
943958 ZoneScoped;
@@ -1388,7 +1403,7 @@ HerderImpl::peerDoesntHave(MessageType type, uint256 const& itemID,
13881403 mPendingEnvelopes .peerDoesntHave (type, itemID, peer);
13891404}
13901405
1391- TxSetXDRFrameConstPtr
1406+ TxSetResult
13921407HerderImpl::getTxSet (Hash const & hash)
13931408{
13941409 return mPendingEnvelopes .getTxSet (hash);
@@ -1639,6 +1654,18 @@ HerderImpl::triggerNextLedger(uint32_t ledgerSeqToTrigger,
16391654 return ;
16401655 }
16411656
1657+ #ifdef BUILD_TESTS
1658+ if (mApp .getConfig ().TESTING_NOMINATE_RANDOM_VALUES &&
1659+ getHerderSCPDriver ().protocolAllowsEmptyTxSetValues ())
1660+ {
1661+ txSetHash = HashUtils::pseudoRandomForTesting ();
1662+ CLOG_INFO (Herder,
1663+ " TESTING_NOMINATE_RANDOM_VALUES: nominating slot {} "
1664+ " with random tx-set hash {}" ,
1665+ slotIndex, hexAbbrev (txSetHash));
1666+ }
1667+ #endif
1668+
16421669 StellarValue newProposedValue = makeStellarValue (
16431670 txSetHash, nextCloseTime, newUpgrades, mApp .getConfig ().NODE_SEED );
16441671 mHerderSCPDriver .nominate (slotIndex, newProposedValue, proposedSet,
@@ -2165,11 +2192,15 @@ HerderImpl::persistSCPState(uint64 slot)
21652192 // saves transaction sets referred by the statement
21662193 for (auto const & h : getValidatedTxSetHashes (e))
21672194 {
2168- auto txSet = mPendingEnvelopes .getTxSet (h);
2169- if (txSet && ! mApp . getPersistentState (). hasTxSet (h ))
2195+ auto result = mPendingEnvelopes .getTxSet (h);
2196+ if (auto * txSetPtr = std::get_if<TxSetXDRFrameConstPtr>(&result ))
21702197 {
2171- txSets.insert (std::make_pair (h, txSet));
2198+ if (*txSetPtr && !mApp .getPersistentState ().hasTxSet (h))
2199+ {
2200+ txSets.insert (std::make_pair (h, *txSetPtr));
2201+ }
21722202 }
2203+ // EmptyTxSet: nothing to persist
21732204 }
21742205 Hash qsHash = Slot::getCompanionQuorumSetHashFromStatement (e.statement );
21752206 SCPQuorumSetPtr qSet = mPendingEnvelopes .getQSet (qsHash);
@@ -2708,11 +2739,34 @@ bool
27082739HerderImpl::verifyStellarValueSignature (StellarValue const & sv)
27092740{
27102741 ZoneScoped;
2711- auto [b, _] = PubKeyUtils::verifySig (
2712- sv.ext .lcValueSignature ().nodeID , sv.ext .lcValueSignature ().signature ,
2713- xdr::xdr_to_opaque (mApp .getNetworkID (), ENVELOPE_TYPE_SCPVALUE ,
2714- sv.txSetHash , sv.closeTime ));
2715- return b;
2742+ switch (sv.ext .v ())
2743+ {
2744+ case STELLAR_VALUE_BASIC :
2745+ // This function should never be called with an unsigned value
2746+ releaseAssert (false );
2747+ case STELLAR_VALUE_SIGNED :
2748+ return PubKeyUtils::verifySig (sv.ext .lcValueSignature ().nodeID ,
2749+ sv.ext .lcValueSignature ().signature ,
2750+ xdr::xdr_to_opaque (mApp .getNetworkID (),
2751+ ENVELOPE_TYPE_SCPVALUE ,
2752+ sv.txSetHash ,
2753+ sv.closeTime ))
2754+ .valid ;
2755+ #ifdef CAP_0083
2756+ case STELLAR_VALUE_EMPTY_TX_SET :
2757+ {
2758+ auto const & ov = sv.ext .proposedValue ();
2759+ return PubKeyUtils::verifySig (
2760+ ov.lcValueSignature .nodeID , ov.lcValueSignature .signature ,
2761+ xdr::xdr_to_opaque (mApp .getNetworkID (),
2762+ ENVELOPE_TYPE_SCPVALUE , ov.txSetHash ,
2763+ sv.closeTime ))
2764+ .valid ;
2765+ }
2766+ #endif // CAP_0083
2767+ default :
2768+ releaseAssert (false );
2769+ }
27162770}
27172771
27182772StellarValue
0 commit comments