Skip to content

Commit

Permalink
Add multiple gateway tests (MystenLabs#2442)
Browse files Browse the repository at this point in the history
  • Loading branch information
lxfind authored Jun 7, 2022
1 parent 70a20fe commit c92bc8d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 25 deletions.
24 changes: 12 additions & 12 deletions crates/sui-core/src/gateway_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,19 +357,19 @@ where
.await?)
}

// Get object locally, try get from the network if not found.
/// This function now always fetch the latest state of the object from validators.
/// We need to do so because it's possible for the state on the gateway to be out-of-dated.
/// TODO: Once we move the gateway to the wallet SDK and serve the wallet locally,
/// we should be able to speculate that the object state is up-to-date most of the time.
/// And when it's out-of-dated in the rare case, we need to be able to understand the error
/// returned from validators and update the object locally so that the wallet can retry.
async fn get_object_internal(&self, object_id: &ObjectID) -> SuiResult<Object> {
Ok(if let Some(object) = self.store.get_object(object_id)? {
debug!(?object_id, ?object, "Fetched object from local store");
object
} else {
let object = self
.download_object_from_authorities(*object_id)
.await?
.into_object()?;
debug!(?object_id, ?object, "Fetched object from validators");
object
})
let object = self
.download_object_from_authorities(*object_id)
.await?
.into_object()?;
debug!(?object_id, ?object, "Fetched object from validators");
Ok(object)
}

async fn get_sui_object<T: SuiMoveObject>(
Expand Down
85 changes: 72 additions & 13 deletions crates/sui-core/src/unit_tests/gateway_state_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async fn transfer_coin(
signer,
coin_object_id,
Some(gas_object_id),
GAS_VALUE_FOR_TESTING,
GAS_VALUE_FOR_TESTING / 10,
recipient,
)
.await?;
Expand Down Expand Up @@ -441,7 +441,7 @@ async fn test_transfer_coin_with_retry() {
// However objects in the transaction should no longer be locked since we reset
// them at the last failed retry.
assert_eq!(gateway.store().pending_transactions().iter().count(), 1);
let (tx_digest, _tx) = gateway
let (tx_digest, tx) = gateway
.store()
.pending_transactions()
.iter()
Expand All @@ -462,17 +462,13 @@ async fn test_transfer_coin_with_retry() {
.fail_after_handle_confirmation = false;

// Retry transaction, and this time it should succeed.
let effects = transfer_coin(
&gateway,
addr1,
&key1,
coin_object.id(),
gas_object.id(),
addr2,
)
.await
.unwrap()
.effects;
let effects = gateway
.execute_transaction(tx)
.await
.unwrap()
.to_effect_response()
.unwrap()
.effects;
let oref = effects.mutated_excluding_gas().next().unwrap();
let updated_obj_ref = &oref.reference;
let new_owner = &oref.owner;
Expand Down Expand Up @@ -639,3 +635,66 @@ async fn test_get_owner_object() {
.unwrap();
assert!(objects.is_empty())
}

#[tokio::test]
async fn test_multiple_gateways() {
let (addr1, key1) = get_key_pair();
let (addr2, _key2) = get_key_pair();

let coin_object1 = Object::with_owner_for_testing(addr1);
let coin_object2 = Object::with_owner_for_testing(addr1);
let coin_object3 = Object::with_owner_for_testing(addr1);
let gas_object = Object::with_owner_for_testing(addr1);

let genesis_objects = authority_genesis_objects(
4,
vec![
coin_object1.clone(),
coin_object2.clone(),
coin_object3.clone(),
gas_object.clone(),
],
);
let gateway1 = create_gateway_state(genesis_objects).await;
let path = tempfile::tempdir().unwrap().into_path();
// gateway2 shares the same set of authorities as gateway1.
let gateway2 = GatewayState::new_with_authorities(path, gateway1.authorities.clone()).unwrap();
let response = transfer_coin(
&gateway1,
addr1,
&key1,
coin_object1.id(),
gas_object.id(),
addr2,
)
.await
.unwrap();
assert!(response.effects.status.is_ok());

// gas_object on gateway2 should be out-of-dated.
// Show that we can still handle the transaction successfully if we use it on gateway2.
let response = transfer_coin(
&gateway2,
addr1,
&key1,
coin_object2.id(),
gas_object.id(),
addr2,
)
.await
.unwrap();
assert!(response.effects.status.is_ok());

// Now we try to use the same gas object on gateway1, and it will still work.
let response = transfer_coin(
&gateway1,
addr1,
&key1,
coin_object3.id(),
gas_object.id(),
addr2,
)
.await
.unwrap();
assert!(response.effects.status.is_ok());
}

0 comments on commit c92bc8d

Please sign in to comment.