use crate::bandwidth_scheduler::{
Bandwidth, BandwidthRequest, BandwidthRequestValues, BandwidthRequests,
BandwidthSchedulerParams, BlockBandwidthRequests,
};
use borsh::{BorshDeserialize, BorshSerialize};
use near_primitives_core::types::{Balance, BlockHeight, Gas, ShardId};
use near_schema_checker_lib::ProtocolSchema;
use std::collections::BTreeMap;
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, ProtocolSchema)]
#[borsh(use_discriminant = true)]
#[repr(u8)]
pub enum ChunkApplyStats {
V0(ChunkApplyStatsV0) = 0,
}
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct ChunkApplyStatsV0 {
pub height: BlockHeight,
pub shard_id: ShardId,
pub is_new_chunk: bool,
pub transactions_num: u64,
pub incoming_receipts_num: u64,
pub receipt_sink: ReceiptSinkStats,
pub bandwidth_scheduler: BandwidthSchedulerStats,
pub balance: BalanceStats,
}
impl ChunkApplyStatsV0 {
pub fn new(height: BlockHeight, shard_id: ShardId) -> ChunkApplyStatsV0 {
ChunkApplyStatsV0 {
height: height,
shard_id: shard_id,
is_new_chunk: false,
transactions_num: 0,
incoming_receipts_num: 0,
bandwidth_scheduler: Default::default(),
balance: Default::default(),
receipt_sink: Default::default(),
}
}
pub fn set_new_bandwidth_requests(
&mut self,
requests: &BandwidthRequests,
params: &BandwidthSchedulerParams,
) {
self.bandwidth_scheduler.set_new_bandwidth_requests(self.shard_id, requests, params);
}
pub fn dummy() -> ChunkApplyStatsV0 {
ChunkApplyStatsV0 {
height: 0,
shard_id: ShardId::new(0),
is_new_chunk: false,
transactions_num: 0,
incoming_receipts_num: 0,
bandwidth_scheduler: Default::default(),
balance: Default::default(),
receipt_sink: Default::default(),
}
}
}
#[derive(Debug, Clone, Default, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct BandwidthSchedulerStats {
pub params: Option<BandwidthSchedulerParams>,
pub prev_bandwidth_requests: BTreeMap<(ShardId, ShardId), Vec<Bandwidth>>,
pub prev_bandwidth_requests_num: u64,
pub time_to_run_ms: u128,
pub granted_bandwidth: BTreeMap<(ShardId, ShardId), Bandwidth>,
pub new_bandwidth_requests: BTreeMap<(ShardId, ShardId), Vec<Bandwidth>>,
}
impl BandwidthSchedulerStats {
pub fn set_prev_bandwidth_requests(
&mut self,
requests: &BlockBandwidthRequests,
params: &BandwidthSchedulerParams,
) {
for (from_shard, shard_requests) in &requests.shards_bandwidth_requests {
Self::add_requests_to_map(
shard_requests,
&mut self.prev_bandwidth_requests,
*from_shard,
params,
);
}
self.prev_bandwidth_requests_num = self.prev_bandwidth_requests.len().try_into().unwrap();
}
pub fn set_new_bandwidth_requests(
&mut self,
from_shard: ShardId,
requests: &BandwidthRequests,
params: &BandwidthSchedulerParams,
) {
Self::add_requests_to_map(requests, &mut self.new_bandwidth_requests, from_shard, params);
}
fn add_requests_to_map(
requests: &BandwidthRequests,
map: &mut BTreeMap<(ShardId, ShardId), Vec<u64>>,
from_shard: ShardId,
params: &BandwidthSchedulerParams,
) {
match requests {
BandwidthRequests::V1(requests_v1) => {
for request in &requests_v1.requests {
map.insert(
(from_shard, request.to_shard.into()),
get_requested_values(request, params),
);
}
}
}
}
}
#[derive(Debug, Clone, Default, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct ReceiptSinkStats {
pub outgoing_limits: BTreeMap<ShardId, OutgoingLimitStats>,
pub forwarded_receipts: BTreeMap<ShardId, ReceiptsStats>,
pub buffered_receipts: BTreeMap<ShardId, ReceiptsStats>,
pub final_outgoing_buffers: BTreeMap<ShardId, ReceiptsStats>,
pub is_outgoing_metadata_ready: BTreeMap<ShardId, bool>,
pub all_outgoing_metadatas_ready: bool,
}
impl ReceiptSinkStats {
pub fn set_outgoing_limits(&mut self, limits: impl Iterator<Item = (ShardId, (u64, Gas))>) {
for (shard_id, (size, gas)) in limits {
self.outgoing_limits.insert(shard_id, OutgoingLimitStats { size, gas });
}
}
}
#[derive(Debug, Clone, Default, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct OutgoingLimitStats {
pub size: u64,
pub gas: Gas,
}
#[derive(Debug, Clone, Default, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct ReceiptsStats {
pub num: u64,
pub total_size: u64,
pub total_gas: u128,
}
impl ReceiptsStats {
pub fn add_receipt(&mut self, size: u64, gas: Gas) {
self.num += 1;
self.total_size += size;
let gas_u128: u128 = gas.as_gas().into();
self.total_gas += gas_u128;
}
}
#[derive(Debug, Clone, Default, BorshSerialize, BorshDeserialize, ProtocolSchema)]
pub struct BalanceStats {
pub tx_burnt_amount: Balance,
pub slashed_burnt_amount: Balance,
pub other_burnt_amount: Balance,
pub gas_deficit_amount: Balance,
pub _deprecated_global_actions_burnt_amount: Balance,
}
fn get_requested_values(
bandwidth_request: &BandwidthRequest,
params: &BandwidthSchedulerParams,
) -> Vec<Bandwidth> {
let values = BandwidthRequestValues::new(params);
let mut res = Vec::new();
for i in 0..bandwidth_request.requested_values_bitmap.len() {
if bandwidth_request.requested_values_bitmap.get_bit(i) {
res.push(values.values[i]);
}
}
res
}