Skip to content

Commit

Permalink
[Gateway API] - Distinguishing objects owning objects from addresses …
Browse files Browse the repository at this point in the history
…owning objects (MystenLabs#2087)

Co-authored-by: Chris Li <[email protected]>
  • Loading branch information
patrickkuo and 666lcz authored May 28, 2022
1 parent a0f5769 commit 86835c1
Show file tree
Hide file tree
Showing 37 changed files with 804 additions and 386 deletions.
40 changes: 20 additions & 20 deletions crates/generate-json-rpc-spec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sui::config::SUI_WALLET_CONFIG;
use sui::wallet_commands::{WalletCommandResult, WalletCommands, WalletContext};
use sui::wallet_commands::{EXAMPLE_NFT_DESCRIPTION, EXAMPLE_NFT_NAME, EXAMPLE_NFT_URL};
use sui_core::gateway_types::{
GetObjectInfoResponse, SuiObjectRef, TransactionEffectsResponse, TransactionResponse,
GetObjectDataResponse, SuiObjectInfo, TransactionEffectsResponse, TransactionResponse,
};
use sui_gateway::api::SuiRpcModule;
use sui_gateway::json_rpc::sui_rpc_doc;
Expand Down Expand Up @@ -108,17 +108,20 @@ async fn create_response_sample(
context.gateway.sync_account_state(address).await?;

// Create coin response
let coins = context.gateway.get_owned_objects(address).await?;
let coins = context
.gateway
.get_objects_owned_by_address(address)
.await?;
let coin = context
.gateway
.get_object_info(coins.first().unwrap().object_id)
.get_object(coins.first().unwrap().object_id)
.await?;

let (example_nft_tx, example_nft) = get_nft_response(&mut context).await?;
let move_package = create_package_object_response(&mut context).await?;
let hero = create_hero_response(&mut context, &coins).await?;
let transfer = create_transfer_response(&mut context, address, &coins).await?;
let coin_split = create_coin_split_response(&mut context, coins).await?;
let coin_split = create_coin_split_response(&mut context, &coins).await?;

let objects = ObjectResponseSample {
example_nft,
Expand All @@ -138,7 +141,7 @@ async fn create_response_sample(

async fn create_package_object_response(
context: &mut WalletContext,
) -> Result<GetObjectInfoResponse, anyhow::Error> {
) -> Result<GetObjectDataResponse, anyhow::Error> {
let result = WalletCommands::Publish {
path: "sui_programmability/tutorial".to_string(),
gas: None,
Expand All @@ -149,7 +152,7 @@ async fn create_package_object_response(
if let WalletCommandResult::Publish(response) = result {
Ok(context
.gateway
.get_object_info(response.package.object_id)
.get_object(response.package.object_id)
.await?)
} else {
panic!()
Expand All @@ -159,7 +162,7 @@ async fn create_package_object_response(
async fn create_transfer_response(
context: &mut WalletContext,
address: SuiAddress,
coins: &[SuiObjectRef],
coins: &[SuiObjectInfo],
) -> Result<TransactionResponse, anyhow::Error> {
let response = WalletCommands::Transfer {
to: address,
Expand All @@ -183,8 +186,8 @@ async fn create_transfer_response(

async fn create_hero_response(
context: &mut WalletContext,
coins: &[SuiObjectRef],
) -> Result<GetObjectInfoResponse, anyhow::Error> {
coins: &[SuiObjectInfo],
) -> Result<GetObjectDataResponse, anyhow::Error> {
// Create hero response
let result = WalletCommands::Publish {
path: "sui_programmability/examples/games".to_string(),
Expand Down Expand Up @@ -217,10 +220,7 @@ async fn create_hero_response(

if let WalletCommandResult::Call(_, effect) = result {
let hero = effect.created.first().unwrap();
Ok(context
.gateway
.get_object_info(hero.reference.object_id)
.await?)
Ok(context.gateway.get_object(hero.reference.object_id).await?)
} else {
panic!()
}
Expand All @@ -231,7 +231,7 @@ async fn create_hero_response(

async fn create_coin_split_response(
context: &mut WalletContext,
coins: Vec<SuiObjectRef>,
coins: &[SuiObjectInfo],
) -> Result<TransactionResponse, anyhow::Error> {
// create coin_split response
let result = WalletCommands::SplitCoin {
Expand All @@ -252,7 +252,7 @@ async fn create_coin_split_response(

async fn get_nft_response(
context: &mut WalletContext,
) -> Result<(TransactionResponse, GetObjectInfoResponse), anyhow::Error> {
) -> Result<(TransactionResponse, GetObjectDataResponse), anyhow::Error> {
// Create example-nft response
let args_json = json!([EXAMPLE_NFT_NAME, EXAMPLE_NFT_DESCRIPTION, EXAMPLE_NFT_URL]);
let args = args_json
Expand All @@ -278,7 +278,7 @@ async fn get_nft_response(
if let WalletCommandResult::Call(certificate, effects) = result {
let object = context
.gateway
.get_object_info(effects.created.first().unwrap().reference.object_id)
.get_object(effects.created.first().unwrap().reference.object_id)
.await?;
let tx = TransactionResponse::EffectResponse(TransactionEffectsResponse {
certificate,
Expand All @@ -292,10 +292,10 @@ async fn get_nft_response(

#[derive(Serialize)]
struct ObjectResponseSample {
pub example_nft: GetObjectInfoResponse,
pub coin: GetObjectInfoResponse,
pub move_package: GetObjectInfoResponse,
pub hero: GetObjectInfoResponse,
pub example_nft: GetObjectDataResponse,
pub coin: GetObjectDataResponse,
pub move_package: GetObjectDataResponse,
pub hero: GetObjectDataResponse,
}

#[derive(Serialize)]
Expand Down
11 changes: 6 additions & 5 deletions crates/sui-core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub use temporary_store::AuthorityTemporaryStore;

mod authority_store;
pub use authority_store::{AuthorityStore, GatewayStore, ReplicaStore, SuiDataStore};
use sui_types::object::Owner;

use self::authority_store::{
generate_genesis_system_object, store_package_and_init_modules_for_genesis,
Expand Down Expand Up @@ -827,7 +828,7 @@ impl AuthorityState {
.compute_object_reference())
}

pub async fn get_object_info(&self, object_id: &ObjectID) -> Result<ObjectRead, SuiError> {
pub async fn get_object_read(&self, object_id: &ObjectID) -> Result<ObjectRead, SuiError> {
match self.database.get_latest_parent_entry(*object_id)? {
None => Ok(ObjectRead::NotExists(*object_id)),
Some((obj_ref, _)) => {
Expand All @@ -853,8 +854,8 @@ impl AuthorityState {
}
}

pub async fn get_owned_objects(&self, account_addr: SuiAddress) -> SuiResult<Vec<ObjectRef>> {
self.database.get_account_objects(account_addr)
pub fn get_owner_objects(&self, owner: Owner) -> SuiResult<Vec<ObjectInfo>> {
self.database.get_owner_objects(owner)
}

pub fn get_total_transaction_number(&self) -> Result<u64, anyhow::Error> {
Expand Down Expand Up @@ -991,9 +992,9 @@ impl AuthorityState {

fn make_account_info(&self, account: SuiAddress) -> Result<AccountInfoResponse, SuiError> {
self.database
.get_account_objects(account)
.get_owner_objects(Owner::AddressOwner(account))
.map(|object_ids| AccountInfoResponse {
object_ids,
object_ids: object_ids.into_iter().map(|id| id.into()).collect(),
owner: account,
})
}
Expand Down
41 changes: 21 additions & 20 deletions crates/sui-core/src/authority/authority_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use sui_types::base_types::SequenceNumber;
use sui_types::batch::{SignedBatch, TxSequenceNumber};
use sui_types::committee::EpochId;
use sui_types::crypto::{AuthoritySignInfo, EmptySignInfo};
use sui_types::object::OBJECT_START_VERSION;
use sui_types::object::{Owner, OBJECT_START_VERSION};
use tracing::{debug, error, trace};
use typed_store::rocks::{DBBatch, DBMap};
use typed_store::{reopen, traits::Map};
Expand Down Expand Up @@ -62,7 +62,7 @@ pub struct SuiDataStore<const ALL_OBJ_VER: bool, const USE_LOCKS: bool, S> {
/// composite key of the SuiAddress of their owner and the object ID of the object.
/// This composite index allows an efficient iterator to list all objected currently owned
/// by a specific user, and their object reference.
owner_index: DBMap<(SuiAddress, ObjectID), ObjectRef>,
owner_index: DBMap<(Owner, ObjectID), ObjectInfo>,

/// This is map between the transaction digest and transactions found in the `transaction_lock`.
/// NOTE: after a lock is deleted (after a certificate is processed) the corresponding entry here
Expand Down Expand Up @@ -164,7 +164,7 @@ impl<
&db,
"objects";<ObjectKey, Object>,
"all_object_versions";<ObjectKey, Object>,
"owner_index";<(SuiAddress, ObjectID), ObjectRef>,
"owner_index";<(Owner, ObjectID), ObjectInfo>,
"transactions";<TransactionDigest, TransactionEnvelope<S>>,
"certificates";<TransactionDigest, CertifiedTransaction>,
"parent_sync";<ObjectRef, TransactionDigest>,
Expand Down Expand Up @@ -283,16 +283,15 @@ impl<
}

// Methods to read the store

pub fn get_account_objects(&self, account: SuiAddress) -> Result<Vec<ObjectRef>, SuiError> {
debug!(?account, "get_account_objects");
pub fn get_owner_objects(&self, owner: Owner) -> Result<Vec<ObjectInfo>, SuiError> {
debug!(?owner, "get_owner_objects");
Ok(self
.owner_index
.iter()
// The object id 0 is the smallest possible
.skip_to(&(account, ObjectID::ZERO))?
.take_while(|((owner, _id), _object_ref)| (owner == &account))
.map(|((_owner, _id), object_ref)| object_ref)
.skip_to(&(owner, ObjectID::ZERO))?
.take_while(|((object_owner, _), _)| (object_owner == &owner))
.map(|(_, object_info)| object_info)
.collect())
}

Expand Down Expand Up @@ -464,10 +463,13 @@ impl<
self.objects.insert(&object_ref.into(), object)?;

// Update the index
if let Some(address) = object.get_single_owner() {
self.owner_index
.insert(&(address, object_ref.0), &object_ref)?;
if object.get_single_owner().is_some() {
self.owner_index.insert(
&(object.owner, object_ref.0),
&ObjectInfo::new(&object_ref, object),
)?;
}

// Update the parent
self.parent_sync
.insert(&object_ref, &object.previous_transaction)?;
Expand Down Expand Up @@ -498,10 +500,9 @@ impl<
)?
.insert_batch(
&self.owner_index,
ref_and_objects.iter().filter_map(|(oref, o)| {
o.get_single_owner()
.map(|address| ((address, oref.0), oref))
}),
ref_and_objects
.iter()
.map(|(oref, o)| ((o.owner, oref.0), ObjectInfo::new(oref, o))),
)?
.insert_batch(
&self.parent_sync,
Expand Down Expand Up @@ -687,13 +688,13 @@ impl<
// We need to call get() on objects because some object that were just deleted may not
// be in the objects list. This can happen if these deleted objects were wrapped in the past,
// and hence will not show up in the input objects.
.filter_map(|(id, _)| objects.get(id).and_then(Object::get_single_owner_and_id))
.filter_map(|(id, _)| objects.get(id).and_then(Object::get_owner_and_id))
.chain(
written
.iter()
.filter_map(|(id, (_, new_object))| match objects.get(id) {
Some(old_object) if old_object.owner != new_object.owner => {
old_object.get_single_owner_and_id()
old_object.get_owner_and_id()
}
_ => None,
}),
Expand Down Expand Up @@ -747,8 +748,8 @@ impl<
.filter_map(|(_id, (object_ref, new_object))| {
trace!(?object_ref, owner =? new_object.owner, "Updating owner_index");
new_object
.get_single_owner_and_id()
.map(|owner_id| (owner_id, object_ref))
.get_owner_and_id()
.map(|owner_id| (owner_id, ObjectInfo::new(object_ref, new_object)))
}),
)?;

Expand Down
Loading

0 comments on commit 86835c1

Please sign in to comment.