Skip to content

Commit

Permalink
Add test (and fix) to ensure idempotent response when confirm after t…
Browse files Browse the repository at this point in the history
…x handle (MystenLabs#1631)
  • Loading branch information
lxfind authored Apr 28, 2022
1 parent 7a0febe commit 5f5a85b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
4 changes: 3 additions & 1 deletion sui_core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ impl AuthorityState {
let transaction_digest = transaction.digest();

// Ensure an idempotent answer.
if self._database.transaction_exists(&transaction_digest)? {
if self._database.transaction_exists(&transaction_digest)?
|| self._database.effects_exists(&transaction_digest)?
{
let transaction_info = self.make_transaction_info(&transaction_digest).await?;
return Ok(transaction_info);
}
Expand Down
38 changes: 38 additions & 0 deletions sui_core/src/unit_tests/authority_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,44 @@ async fn test_authority_persist() {
assert_eq!(obj2.owner, recipient);
}

#[tokio::test]
async fn test_idempotent_reversed_confirmation() {
// In this test we exercise the case where an authority first receive the certificate,
// and then receive the raw transaction latter. We should still ensure idempotent
// response and be able to get back the same result.
let recipient = dbg_addr(2);
let (sender, sender_key) = get_key_pair();

let object = Object::with_owner_for_testing(sender);
let object_ref = object.compute_object_reference();
let gas_object = Object::with_owner_for_testing(sender);
let gas_object_ref = gas_object.compute_object_reference();
let authority_state = init_state_with_objects([object, gas_object]).await;

let certified_transfer_transaction = init_certified_transfer_transaction(
sender,
&sender_key,
recipient,
object_ref,
gas_object_ref,
&authority_state,
);
let result1 = authority_state
.handle_confirmation_transaction(ConfirmationTransaction::new(
certified_transfer_transaction.clone(),
))
.await;
assert!(result1.is_ok());
let result2 = authority_state
.handle_transaction(certified_transfer_transaction.transaction)
.await;
assert!(result2.is_ok());
assert_eq!(
result1.unwrap().signed_effects.unwrap().effects,
result2.unwrap().signed_effects.unwrap().effects
);
}

// helpers

#[cfg(test)]
Expand Down

0 comments on commit 5f5a85b

Please sign in to comment.