Skip to content

Commit 0214a43

Browse files
committed
[Consensus Observer] Small message handling tweaks.
1 parent d994a43 commit 0214a43

1 file changed

Lines changed: 92 additions & 6 deletions

File tree

consensus/src/consensus_observer/network/observer_message.rs

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -783,10 +783,12 @@ impl BlockTransactionPayload {
783783
}
784784

785785
/// Returns the proofs of the transaction payload
786-
pub fn payload_proofs_v2(&self) -> Vec<ProofOfStore<BatchInfoExt>> {
786+
pub fn payload_proofs_v2(&self) -> Result<Vec<ProofOfStore<BatchInfoExt>>, Error> {
787787
match self {
788-
BlockTransactionPayload::OptQuorumStoreV2(payload, _) => payload.proofs(),
789-
_ => unreachable!(),
788+
BlockTransactionPayload::OptQuorumStoreV2(payload, _) => Ok(payload.proofs()),
789+
_ => Err(Error::InvalidMessageError(
790+
"Transaction payload is not an OptQuorumStoreV2 variant!".into(),
791+
)),
790792
}
791793
}
792794

@@ -857,7 +859,7 @@ impl BlockTransactionPayload {
857859
// Get the batches in the block transaction payload
858860
let payload_proofs = self
859861
.payload_proofs()
860-
.expect("non-OptQSV2 batch is expected");
862+
.map_err(|e| Error::InvalidMessageError(e.to_string()))?;
861863
let payload_batches: Vec<&BatchInfo> =
862864
payload_proofs.iter().map(|proof| proof.info()).collect();
863865

@@ -946,7 +948,7 @@ impl BlockTransactionPayload {
946948
expected_proofs: &[ProofOfStore<BatchInfoExt>],
947949
) -> Result<(), Error> {
948950
// Get the batches in the block transaction payload
949-
let payload_proofs = self.payload_proofs_v2();
951+
let payload_proofs = self.payload_proofs_v2()?;
950952
let payload_batches: Vec<&BatchInfoExt> =
951953
payload_proofs.iter().map(|proof| proof.info()).collect();
952954

@@ -1207,7 +1209,7 @@ impl BlockPayload {
12071209
))
12081210
})?;
12091211
} else {
1210-
let payload_proofs = self.transaction_payload.payload_proofs_v2();
1212+
let payload_proofs = self.transaction_payload.payload_proofs_v2()?;
12111213
let validator_verifier = &epoch_state.verifier;
12121214
payload_proofs
12131215
.par_iter()
@@ -1513,6 +1515,90 @@ mod test {
15131515
.unwrap();
15141516
}
15151517

1518+
#[test]
1519+
fn test_verify_against_ordered_payload_optqs_v2_variant_mismatch() {
1520+
// Build an empty V2 ordered block payload (as produced by validators when
1521+
// enable_opt_qs_v2_payload_tx is enabled).
1522+
let v2_ordered_payload = Payload::OptQuorumStore(OptQuorumStorePayload::new_v2(
1523+
Vec::<(BatchInfoExt, Vec<SignedTransaction>)>::new().into(),
1524+
Vec::<BatchInfoExt>::new().into(),
1525+
Vec::<ProofOfStore<BatchInfoExt>>::new().into(),
1526+
PayloadExecutionLimit::MaxTransactionsToExecute(100),
1527+
));
1528+
1529+
// Verify that non-V2 stored variants fail verification
1530+
let hybrid_payload = BlockTransactionPayload::new_quorum_store_inline_hybrid(
1531+
vec![],
1532+
vec![],
1533+
None,
1534+
None,
1535+
vec![],
1536+
false, // Produces the legacy QuorumStoreInlineHybrid variant
1537+
);
1538+
let error = hybrid_payload
1539+
.verify_against_ordered_payload(&v2_ordered_payload)
1540+
.unwrap_err();
1541+
assert_matches!(error, Error::InvalidMessageError(_));
1542+
1543+
// Verify that the QuorumStoreInlineHybridV2 variant also fails verification
1544+
let hybrid_v2_payload = BlockTransactionPayload::new_quorum_store_inline_hybrid(
1545+
vec![],
1546+
vec![],
1547+
None,
1548+
None,
1549+
vec![],
1550+
true, // Produces QuorumStoreInlineHybridV2
1551+
);
1552+
let error = hybrid_v2_payload
1553+
.verify_against_ordered_payload(&v2_ordered_payload)
1554+
.unwrap_err();
1555+
assert_matches!(error, Error::InvalidMessageError(_));
1556+
1557+
// Verify that the OptQuorumStoreV1 variant fails verification
1558+
let optqs_v1_payload =
1559+
BlockTransactionPayload::new_opt_quorum_store(vec![], vec![], None, None, vec![]);
1560+
let error = optqs_v1_payload
1561+
.verify_against_ordered_payload(&v2_ordered_payload)
1562+
.unwrap_err();
1563+
assert_matches!(error, Error::InvalidMessageError(_));
1564+
1565+
// Verify that the OptQuorumStoreV2 variant with matching batches and limit passes verification
1566+
let optqs_v2_payload = BlockTransactionPayload::new_opt_quorum_store_v2(
1567+
vec![],
1568+
vec![],
1569+
Some(100),
1570+
None,
1571+
vec![],
1572+
);
1573+
optqs_v2_payload
1574+
.verify_against_ordered_payload(&v2_ordered_payload)
1575+
.unwrap();
1576+
}
1577+
1578+
#[test]
1579+
fn test_verify_against_ordered_payload_optqs_v1_variant_mismatch() {
1580+
// Build an empty V1 ordered block payload.
1581+
let v1_ordered_payload = Payload::OptQuorumStore(OptQuorumStorePayload::new(
1582+
Vec::<InlineBatch<BatchInfo>>::new().into(),
1583+
Vec::new().into(),
1584+
Vec::<ProofOfStore<BatchInfo>>::new().into(),
1585+
PayloadExecutionLimit::MaxTransactionsToExecute(100),
1586+
));
1587+
1588+
// Verify that an OptQuorumStoreV2 transaction payload returns InvalidMessageError
1589+
let optqs_v2_payload = BlockTransactionPayload::new_opt_quorum_store_v2(
1590+
vec![],
1591+
vec![],
1592+
Some(100),
1593+
None,
1594+
vec![],
1595+
);
1596+
let error = optqs_v2_payload
1597+
.verify_against_ordered_payload(&v1_ordered_payload)
1598+
.unwrap_err();
1599+
assert_matches!(error, Error::InvalidMessageError(_));
1600+
}
1601+
15161602
#[test]
15171603
fn test_verify_commit_proof() {
15181604
// Create a ledger info with an empty signature set

0 commit comments

Comments
 (0)