@@ -5848,27 +5848,46 @@ TEST_CASE("SCP message capture from previous ledger", "[herder]")
5848
5848
},
5849
5849
2 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false );
5850
5850
5851
- // Return the number of entries in a node's scphistory table for the given
5852
- // ledger number
5853
- auto getNumSCPHistoryEntries = [&](Application::pointer node,
5854
- uint32_t ledgerNum) {
5855
- auto & db = node->getDatabase ();
5856
- auto prep = db.getPreparedStatement (
5857
- " SELECT COUNT(*) FROM scphistory WHERE ledgerseq = :l" );
5858
- auto & st = prep.statement ();
5859
- st.exchange (soci::use (ledgerNum));
5860
- uint32_t count;
5861
- st.exchange (soci::into (count));
5862
- st.define_and_bind ();
5863
- st.execute (true );
5864
- return count;
5865
- };
5851
+ // Check that a node's scphistory table for a given ledger has the correct
5852
+ // number of entries of each type in `expectedTypes`
5853
+ auto checkSCPHistoryEntries =
5854
+ [&](Application::pointer node, uint32_t ledgerNum,
5855
+ UnorderedMap<SCPStatementType, size_t > const & expectedTypes) {
5856
+ // Prepare query
5857
+ auto & db = node->getDatabase ();
5858
+ auto prep = db.getPreparedStatement (
5859
+ " SELECT envelope FROM scphistory WHERE ledgerseq = :l" );
5860
+ auto & st = prep.statement ();
5861
+ st.exchange (soci::use (ledgerNum));
5862
+ std::string envStr;
5863
+ st.exchange (soci::into (envStr));
5864
+ st.define_and_bind ();
5865
+ st.execute (false );
5866
+
5867
+ // Count the number of entries of each type
5868
+ UnorderedMap<SCPStatementType, size_t > actualTypes;
5869
+ while (st.fetch ())
5870
+ {
5871
+ Value v;
5872
+ decoder::decode_b64 (envStr, v);
5873
+ SCPEnvelope env;
5874
+ xdr::xdr_from_opaque (v, env);
5875
+ ++actualTypes[env.statement .pledges .type ()];
5876
+ }
5877
+
5878
+ REQUIRE (actualTypes == expectedTypes);
5879
+ };
5880
+
5881
+ // A has 1 CONFIRM and 1 EXTERNALIZE in its scphistory table for ledger 2.
5882
+ checkSCPHistoryEntries (A, 2 ,
5883
+ {{SCPStatementType::SCP_ST_CONFIRM, 1 },
5884
+ {SCPStatementType::SCP_ST_EXTERNALIZE, 1 }});
5885
+
5886
+ // B has 2 EXTERNALIZEs in its scphistory table for ledger 2.
5887
+ checkSCPHistoryEntries (B, 2 , {{SCPStatementType::SCP_ST_EXTERNALIZE, 2 }});
5866
5888
5867
- // A and B should have 2 entries in their scphistory table for ledger 2. C
5868
- // should have 0.
5869
- REQUIRE (getNumSCPHistoryEntries (A, 2 ) == 2 );
5870
- REQUIRE (getNumSCPHistoryEntries (B, 2 ) == 2 );
5871
- REQUIRE (getNumSCPHistoryEntries (C, 2 ) == 0 );
5889
+ // C has no entries in its scphistory table for ledger 2.
5890
+ checkSCPHistoryEntries (C, 2 , {});
5872
5891
5873
5892
// Get messages from A and B
5874
5893
HerderImpl& herderA = dynamic_cast <HerderImpl&>(A->getHerder ());
@@ -5910,9 +5929,12 @@ TEST_CASE("SCP message capture from previous ledger", "[herder]")
5910
5929
},
5911
5930
2 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false );
5912
5931
5913
- // A and B should now have 3 entries in their scphistory table for ledger 2.
5914
- REQUIRE (getNumSCPHistoryEntries (A, 2 ) == 3 );
5915
- REQUIRE (getNumSCPHistoryEntries (B, 2 ) == 3 );
5932
+ // A and B should now each have 3 EXTERNALIZEs in their scphistory table for
5933
+ // ledger 2. A's CONFIRM entry has been replaced with an EXTERNALIZE.
5934
+ UnorderedMap<SCPStatementType, size_t > const expectedTypes = {
5935
+ {SCPStatementType::SCP_ST_EXTERNALIZE, 3 }};
5936
+ checkSCPHistoryEntries (A, 2 , expectedTypes);
5937
+ checkSCPHistoryEntries (B, 2 , expectedTypes);
5916
5938
5917
5939
// Connect C to B and crank C to catch up with A and B
5918
5940
simulation->addConnection (validatorCKey.getPublicKey (),
@@ -5921,8 +5943,8 @@ TEST_CASE("SCP message capture from previous ledger", "[herder]")
5921
5943
[&]() { return C->getLedgerManager ().getLastClosedLedgerNum () == 3 ; },
5922
5944
2 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false );
5923
5945
5924
- // C should have 3 entries in its scphistory table for ledger 2. This check
5925
- // ensures that C does not double count messages from ledger 2 when closing
5926
- // ledger 3.
5927
- REQUIRE ( getNumSCPHistoryEntries ( C, 2 ) == 3 );
5946
+ // C should have 3 EXTERNALIZEs in its scphistory table for ledger 2. This
5947
+ // check ensures that C does not double count messages from ledger 2 when
5948
+ // closing ledger 3.
5949
+ checkSCPHistoryEntries ( C, 2 , expectedTypes );
5928
5950
}
0 commit comments