Skip to content

Commit

Permalink
with_tracing to instrument info or error logs (MystenLabs#11324)
Browse files Browse the repository at this point in the history
## Description 

Wrapper function to help instrument info or error logs. info logs are
still subject to sampling, but error logs will always log.

```
curl --location 'http://127.0.0.1:9000' \
--header 'Content-Type: application/json' \
--data '{
    "method": "suix_getDynamicFieldObject",
    "jsonrpc": "2.0",
    "params": [
        "0x7d1237b9f8ab28ce64322b1f7b09d18909205a55c0f301f36838abbbfb234516",
        {
            "type": "address",
            "value": "0x82d7715ff1213dbfd740b5761133c6b7b19d5a5d1e1854d74ba6be53b36a9ca0"
        }
    ],
    "id": 1
}'
```
```
2023-04-25T19:55:34.558917Z ERROR connection{remote_addr=127.0.0.1:63470 conn_id=6}:get_dynamic_field_object{parent_object_id=0x7d1237b9f8ab28ce64322b1f7b09d18909205a55c0f301f36838abbbfb234516 name=DynamicFieldName { type_: Address, value: String("0x82d7715ff1213dbfd740b5761133c6b7b19d5a5d1e1854d74ba6be53b36a9ca0") }}: sui_json_rpc::indexer_api: get_dynamic_field_object failed: Call(Failed(Cannot find dynamic field [DynamicFieldName { type_: Address, value: String("0x82d7715ff1213dbfd740b5761133c6b7b19d5a5d1e1854d74ba6be53b36a9ca0") }] for object [0x7d1237b9f8ab28ce64322b1f7b09d18909205a55c0f301f36838abbbfb234516].))
```


```
curl --location 'http://127.0.0.1:9000' \
--header 'Content-Type: application/json' \
--data '{
    "jsonrpc": "2.0",
    "method": "suix_getOwnedObjects",
    "params": [
        "0xadfb89b000e97a30bd485bffbff80f883096a8a98cdce33641ec924393d8fbe8",
        {
            "options": {
                "showType": true,
                "showOwner": false,
                "showPreviousTransaction": false,
                "showDisplay": false,
                "showContent": true,
                "showBcs": false,
                "showStorageRebate": false
            }
        }
    ],
    "id": 1
}'
```

```
2023-04-25T19:56:01.066520Z  INFO connection{remote_addr=127.0.0.1:63477 conn_id=12}:get_owned_objects{address=0xadfb89b000e97a30bd485bffbff80f883096a8a98cdce33641ec924393d8fbe8 query=Some(SuiObjectResponseQuery { filter: None, options: Some(SuiObjectDataOptions { show_type: true, show_owner: false, show_previous_transaction: false, show_display: false, show_content: true, show_bcs: false, show_storage_rebate: false }) }) cursor=None limit=None}:multi_get_objects{object_ids=[] options=Some(SuiObjectDataOptions { show_type: true, show_owner: false, show_previous_transaction: false, show_display: false, show_content: true, show_bcs: false, show_storage_rebate: false })}: sui_json_rpc::read_api: multi_get_objects
```

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
wlmyng authored Apr 27, 2023
1 parent 3c5d52b commit 9c416d4
Show file tree
Hide file tree
Showing 6 changed files with 734 additions and 667 deletions.
253 changes: 131 additions & 122 deletions crates/sui-json-rpc/src/coin_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use sui_types::parse_sui_struct_tag;

use crate::api::{cap_page_limit, CoinReadApiServer, JsonRpcMetrics};
use crate::error::Error;
use crate::SuiRpcModule;
use crate::{with_tracing, SuiRpcModule};

pub struct CoinReadApi {
state: Arc<AuthorityState>,
Expand Down Expand Up @@ -158,25 +158,26 @@ impl CoinReadApiServer for CoinReadApi {
cursor: Option<ObjectID>,
limit: Option<usize>,
) -> RpcResult<CoinPage> {
info!("get_coins");
let coin_type_tag = TypeTag::Struct(Box::new(match coin_type {
Some(c) => parse_sui_struct_tag(&c)?,
None => GAS::type_(),
}));

let cursor = match cursor {
Some(c) => (coin_type_tag.to_string(), c),
// If cursor is not specified, we need to start from the beginning of the coin type, which is the minimal possible ObjectID.
None => (coin_type_tag.to_string(), ObjectID::ZERO),
};

let coins = self
.get_coins_iterator(
owner, cursor, limit, true, // only care about one type of coin
)
.await?;
with_tracing!("get_coins", async move {
let coin_type_tag = TypeTag::Struct(Box::new(match coin_type {
Some(c) => parse_sui_struct_tag(&c)?,
None => GAS::type_(),
}));

let cursor = match cursor {
Some(c) => (coin_type_tag.to_string(), c),
// If cursor is not specified, we need to start from the beginning of the coin type, which is the minimal possible ObjectID.
None => (coin_type_tag.to_string(), ObjectID::ZERO),
};

let coins = self
.get_coins_iterator(
owner, cursor, limit, true, // only care about one type of coin
)
.await?;

Ok(coins)
Ok(coins)
})
}

#[instrument(skip(self))]
Expand All @@ -187,42 +188,43 @@ impl CoinReadApiServer for CoinReadApi {
cursor: Option<ObjectID>,
limit: Option<usize>,
) -> RpcResult<CoinPage> {
info!("get_all_coins");
let cursor = match cursor {
Some(object_id) => {
let obj = self
.state
.get_object(&object_id)
.await
.map_err(Error::from)?;
match obj {
Some(obj) => {
let coin_type = obj.coin_type_maybe();
if coin_type.is_none() {
Err(anyhow!(
"Invalid Cursor {:?}, Object is not a coin",
object_id
))
} else {
Ok((coin_type.unwrap().to_string(), object_id))
with_tracing!("get_all_coins", async move {
let cursor = match cursor {
Some(object_id) => {
let obj = self
.state
.get_object(&object_id)
.await
.map_err(Error::from)?;
match obj {
Some(obj) => {
let coin_type = obj.coin_type_maybe();
if coin_type.is_none() {
Err(anyhow!(
"Invalid Cursor {:?}, Object is not a coin",
object_id
))
} else {
Ok((coin_type.unwrap().to_string(), object_id))
}
}
None => Err(anyhow!("Invalid Cursor {:?}, Object not found", object_id)),
}
None => Err(anyhow!("Invalid Cursor {:?}, Object not found", object_id)),
}
}
None => {
// If cursor is None, start from the beginning
Ok((String::from_utf8([0u8].to_vec()).unwrap(), ObjectID::ZERO))
}
}?;
None => {
// If cursor is None, start from the beginning
Ok((String::from_utf8([0u8].to_vec()).unwrap(), ObjectID::ZERO))
}
}?;

let coins = self
.get_coins_iterator(
owner, cursor, limit, false, // return all types of coins
)
.await?;
let coins = self
.get_coins_iterator(
owner, cursor, limit, false, // return all types of coins
)
.await?;

Ok(coins)
Ok(coins)
})
}

#[instrument(skip(self))]
Expand All @@ -231,92 +233,99 @@ impl CoinReadApiServer for CoinReadApi {
owner: SuiAddress,
coin_type: Option<String>,
) -> RpcResult<Balance> {
info!("get_balance");
let coin_type = TypeTag::Struct(Box::new(match coin_type {
Some(c) => parse_sui_struct_tag(&c)?,
None => GAS::type_(),
}));
let balance = self
.state
.indexes
.as_ref()
.ok_or(Error::SuiError(SuiError::IndexStoreNotAvailable))?
.get_balance(owner, coin_type.clone())
.await
.map_err(|e: SuiError| {
debug!(?owner, "Failed to get balance with error: {:?}", e);
Error::from(e)
})?;
Ok(Balance {
coin_type: coin_type.to_string(),
coin_object_count: balance.num_coins as usize,
total_balance: balance.balance as u128,
// note: LockedCoin is deprecated
locked_balance: Default::default(),
with_tracing!("get_balance", async move {
let coin_type = TypeTag::Struct(Box::new(match coin_type {
Some(c) => parse_sui_struct_tag(&c)?,
None => GAS::type_(),
}));
let balance = self
.state
.indexes
.as_ref()
.ok_or(Error::SuiError(SuiError::IndexStoreNotAvailable))?
.get_balance(owner, coin_type.clone())
.await
.map_err(|e: SuiError| {
debug!(?owner, "Failed to get balance with error: {:?}", e);
Error::from(e)
})?;
Ok(Balance {
coin_type: coin_type.to_string(),
coin_object_count: balance.num_coins as usize,
total_balance: balance.balance as u128,
// note: LockedCoin is deprecated
locked_balance: Default::default(),
})
})
}

#[instrument(skip(self))]
async fn get_all_balances(&self, owner: SuiAddress) -> RpcResult<Vec<Balance>> {
info!("get_all_balances");
let all_balance = self
.state
.indexes
.as_ref()
.ok_or(Error::SuiError(SuiError::IndexStoreNotAvailable))?
.get_all_balance(owner)
.await
.map_err(|e: SuiError| {
debug!(?owner, "Failed to get all balance with error: {:?}", e);
Error::from(e)
})?;
Ok(all_balance
.iter()
.map(|(coin_type, balance)| {
Balance {
coin_type: coin_type.to_string(),
coin_object_count: balance.num_coins as usize,
total_balance: balance.balance as u128,
// note: LockedCoin is deprecated
locked_balance: Default::default(),
}
})
.collect())
with_tracing!("get_all_balances", async move {
let all_balance = self
.state
.indexes
.as_ref()
.ok_or(Error::SuiError(SuiError::IndexStoreNotAvailable))?
.get_all_balance(owner)
.await
.map_err(|e: SuiError| {
debug!(?owner, "Failed to get all balance with error: {:?}", e);
Error::from(e)
})?;
Ok(all_balance
.iter()
.map(|(coin_type, balance)| {
Balance {
coin_type: coin_type.to_string(),
coin_object_count: balance.num_coins as usize,
total_balance: balance.balance as u128,
// note: LockedCoin is deprecated
locked_balance: Default::default(),
}
})
.collect())
})
}

#[instrument(skip(self))]
async fn get_coin_metadata(&self, coin_type: String) -> RpcResult<Option<SuiCoinMetadata>> {
info!("get_coin_metadata");
let coin_struct = parse_sui_struct_tag(&coin_type)?;

let metadata_object = self
.find_package_object(
&coin_struct.address.into(),
CoinMetadata::type_(coin_struct),
)
.await
.ok();

Ok(metadata_object.and_then(|v: Object| v.try_into().ok()))
with_tracing!("get_coin_metadata", async move {
let coin_struct = parse_sui_struct_tag(&coin_type)?;

let metadata_object = self
.find_package_object(
&coin_struct.address.into(),
CoinMetadata::type_(coin_struct),
)
.await
.ok();

Ok(metadata_object.and_then(|v: Object| v.try_into().ok()))
})
}

#[instrument(skip(self))]
async fn get_total_supply(&self, coin_type: String) -> RpcResult<Supply> {
info!("get_total_supply");
let coin_struct = parse_sui_struct_tag(&coin_type)?;

Ok(if GAS::is_gas(&coin_struct) {
Supply { value: 0 }
} else {
let treasury_cap_object = self
.find_package_object(&coin_struct.address.into(), TreasuryCap::type_(coin_struct))
.await?;
with_tracing!("get_total_supply", async move {
let coin_struct = parse_sui_struct_tag(&coin_type)?;

Ok(if GAS::is_gas(&coin_struct) {
Supply { value: 0 }
} else {
let treasury_cap_object = self
.find_package_object(
&coin_struct.address.into(),
TreasuryCap::type_(coin_struct),
)
.await?;

let treasury_cap = TreasuryCap::from_bcs_bytes(
treasury_cap_object.data.try_as_move().unwrap().contents(),
)
.map_err(Error::from)?;
treasury_cap.total_supply
let treasury_cap = TreasuryCap::from_bcs_bytes(
treasury_cap_object.data.try_as_move().unwrap().contents(),
)
.map_err(Error::from)?;
treasury_cap.total_supply
})
})
}
}
50 changes: 28 additions & 22 deletions crates/sui-json-rpc/src/governance_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use sui_types::sui_system_state::{

use crate::api::{GovernanceReadApiServer, JsonRpcMetrics};
use crate::error::Error;
use crate::{ObjectProvider, SuiRpcModule};
use crate::{with_tracing, ObjectProvider, SuiRpcModule};

pub struct GovernanceReadApi {
state: Arc<AuthorityState>,
Expand Down Expand Up @@ -255,43 +255,49 @@ impl GovernanceReadApiServer for GovernanceReadApi {
&self,
staked_sui_ids: Vec<ObjectID>,
) -> RpcResult<Vec<DelegatedStake>> {
info!("get_stakes_by_ids");
Ok(self.get_stakes_by_ids(staked_sui_ids).await?)
with_tracing!("get_stakes_by_ids", async move {
Ok(self.get_stakes_by_ids(staked_sui_ids).await?)
})
}

#[instrument(skip(self))]
async fn get_stakes(&self, owner: SuiAddress) -> RpcResult<Vec<DelegatedStake>> {
info!("get_stakes");
Ok(self.get_stakes(owner).await?)
with_tracing!(
"get_stakes",
async move { Ok(self.get_stakes(owner).await?) }
)
}

#[instrument(skip(self))]
async fn get_committee_info(&self, epoch: Option<BigInt<u64>>) -> RpcResult<SuiCommittee> {
info!("get_committee_info");
Ok(self
.state
.committee_store()
.get_or_latest_committee(epoch.map(|e| *e))
.map(|committee| committee.into())
.map_err(Error::from)?)
with_tracing!("get_committee_info", async move {
Ok(self
.state
.committee_store()
.get_or_latest_committee(epoch.map(|e| *e))
.map(|committee| committee.into())
.map_err(Error::from)?)
})
}

#[instrument(skip(self))]
async fn get_latest_sui_system_state(&self) -> RpcResult<SuiSystemStateSummary> {
info!("get_latest_sui_system_state");
Ok(self
.state
.database
.get_sui_system_state_object()
.map_err(Error::from)?
.into_sui_system_state_summary())
with_tracing!("get_latest_sui_system_state", async move {
Ok(self
.state
.database
.get_sui_system_state_object()
.map_err(Error::from)?
.into_sui_system_state_summary())
})
}

#[instrument(skip(self))]
async fn get_reference_gas_price(&self) -> RpcResult<BigInt<u64>> {
info!("get_reference_gas_price");
let epoch_store = self.state.load_epoch_store_one_call_per_task();
Ok(epoch_store.reference_gas_price().into())
with_tracing!("get_reference_gas_price", async move {
let epoch_store = self.state.load_epoch_store_one_call_per_task();
Ok(epoch_store.reference_gas_price().into())
})
}
}

Expand Down
Loading

0 comments on commit 9c416d4

Please sign in to comment.