Skip to content

Commit 936329c

Browse files
authored
Corrected state size calculation logic (#371)
* fix to calculate state size * clippy * fix calculate state size limit * changelog
1 parent 17db12a commit 936329c

File tree

6 files changed

+52
-14
lines changed

6 files changed

+52
-14
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased](https://github.com/near/read-rpc/compare/main...develop)
99

10+
### What's Changed
11+
* Corrected state size calculation logic.
12+
* Integrated cargo_pkg_version metric to reflect the current server version.
13+
* Delete unnecessary debug logs about update blocks by finalities
14+
1015
## [0.3.1](https://github.com/near/read-rpc/releases/tag/v0.3.1)
1116

1217
### Supported Nearcore Version

rpc-server/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ impl ServerContext {
154154
let compiled_contract_code_cache =
155155
std::sync::Arc::new(CompiledCodeCache::new(contract_code_cache_size_in_bytes));
156156

157+
crate::metrics::CARGO_PKG_VERSION
158+
.with_label_values(&[NEARD_VERSION])
159+
.inc();
160+
157161
Ok(Self {
158162
s3_client,
159163
db_manager: std::sync::Arc::new(Box::new(db_manager)),

rpc-server/src/metrics.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use actix_web::{get, Responder};
2-
use prometheus::{Encoder, IntCounterVec, IntGauge, IntGaugeVec, Opts};
2+
use prometheus::{CounterVec, Encoder, IntCounterVec, IntGauge, IntGaugeVec, Opts};
33

44
type Result<T, E> = std::result::Result<T, E>;
55

@@ -113,6 +113,14 @@ lazy_static! {
113113
"Optimistic updating status. 0: working, 1: not working",
114114
).unwrap();
115115

116+
pub(crate) static ref CARGO_PKG_VERSION: CounterVec = {
117+
let opts = Opts::new("cargo_pkg_version", "Cargo package version. This is used to track the version of the running server.")
118+
.variable_label("version");
119+
let counter_vec = CounterVec::new(opts, &["version"]).expect("metric can be created");
120+
prometheus::register(Box::new(counter_vec.clone())).unwrap();
121+
counter_vec
122+
};
123+
116124
pub(crate) static ref LEGACY_DATABASE_TX_DETAILS: IntCounterVec = register_int_counter_vec(
117125
"legacy_database_tx_details",
118126
"Total number of calls to the legacy database for transaction details",

rpc-server/src/modules/blocks/mod.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,6 @@ impl BlocksInfoByFinality {
335335
// Update final block info in the cache.
336336
// Executes every second.
337337
pub async fn update_final_block(&self, block_info: BlockInfo) {
338-
tracing::debug!(
339-
"Update final block info: {:?}",
340-
block_info.block_cache.block_height
341-
);
342338
let mut final_block_lock = self.final_block.write().await;
343339
final_block_lock.block_cache = block_info.block_cache;
344340
final_block_lock.block_view = block_info.block_view;
@@ -348,11 +344,6 @@ impl BlocksInfoByFinality {
348344
// Update optimistic block changes and optimistic block info in the cache.
349345
// Executes every second.
350346
pub async fn update_optimistic_block(&self, block_info: BlockInfo) {
351-
tracing::debug!(
352-
"Update optimistic block info: {:?}",
353-
block_info.block_cache.block_height
354-
);
355-
356347
let mut optimistic_changes_lock = self.optimistic_changes.write().await;
357348
optimistic_changes_lock.account_changes = block_info.changes_in_block_account_map().await;
358349

rpc-server/src/modules/queries/contract_runner/mod.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use std::collections::HashMap;
22

3-
use near_vm_runner::ContractRuntimeCache;
4-
53
use crate::modules::blocks::BlocksInfoByFinality;
64
use code_storage::CodeStorage;
5+
use near_vm_runner::ContractRuntimeCache;
76

87
mod code_storage;
98

@@ -137,20 +136,39 @@ pub async fn run_contract(
137136
block_hash: block.block_hash,
138137
}
139138
})?;
139+
println!("Contract code len {}", code.data.len());
140140
contract_code_cache.put(code_hash, code.data.clone()).await;
141141
Contract::new(Some(code.data), code_hash)
142142
}
143143
}
144144
};
145145

146+
// We need to calculate the state size of the contract to determine if we should prefetch the state or not.
147+
// The state size is the storage usage minus the code size.
148+
// If the state size is less than the prefetch_state_size_limit, we prefetch the state.
149+
let code_len = if let Some(contract_code) = &contract_code.contract_code {
150+
contract_code.code().len()
151+
} else if let Some(code) = contract_code_cache.get(&code_hash).await {
152+
code.len()
153+
} else {
154+
db_manager
155+
.get_contract_code(account_id, block.block_height, "query_call_function")
156+
.await
157+
.map(|code| code.data.len())
158+
.unwrap_or_default()
159+
};
160+
let state_size = contract
161+
.data
162+
.storage_usage()
163+
.saturating_sub(code_len as u64);
146164
// Init an external database interface for the Runtime logic
147165
let code_storage = CodeStorage::init(
148166
db_manager.clone(),
149167
account_id.clone(),
150168
block.block_height,
151169
validators,
152170
optimistic_data,
153-
contract.data.storage_usage() <= prefetch_state_size_limit,
171+
state_size <= prefetch_state_size_limit,
154172
)
155173
.await;
156174

rpc-server/src/modules/queries/methods.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,19 @@ async fn view_state(
443443
block_hash: block.block_hash,
444444
},
445445
)?;
446-
if prefix.is_empty() && account.data.storage_usage() > data.prefetch_state_size_limit {
446+
447+
// Calculate the state size excluding the contract code size to check if it's too large to fetch.
448+
// The state size is the storage usage minus the code size.
449+
// more details: nearcore/runtime/runtime/src/state_viewer/mod.rs:150
450+
let code_len = data
451+
.db_manager
452+
.get_contract_code(account_id, block.block_height, "query_view_state")
453+
.await
454+
.map(|code| code.data.len() as u64)
455+
.unwrap_or_default();
456+
let state_size = account.data.storage_usage().saturating_sub(code_len);
457+
// If the prefix is empty and the state size is larger than the limit, return an error.
458+
if prefix.is_empty() && state_size > data.prefetch_state_size_limit {
447459
return Err(
448460
near_jsonrpc::primitives::types::query::RpcQueryError::TooLargeContractState {
449461
contract_account_id: account_id.clone(),

0 commit comments

Comments
 (0)