Skip to content
18 changes: 4 additions & 14 deletions data_structures/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,20 +1742,10 @@ pub struct SupplyInfo {
pub blocks_minted: u32,
/// WIT minted through block creation
pub blocks_minted_reward: u64,
/// Number of blocks missing
pub blocks_missing: u32,
/// WIT missing because a block was not created
pub blocks_missing_reward: u64,
/// Amount of in-flight data requests
pub in_flight_requests: u32,
/// Supply currently locked in data requests
pub locked_wits_by_requests: u64,
/// Current unlocked supply
pub current_unlocked_supply: u64,
/// Current locked supply
pub current_locked_supply: u64,
/// Maximum supply: the number of nanowits that will ever exist
pub maximum_supply: u64,
/// Current staked supply
pub current_staked_supply: u64,
/// Genesis supply
pub genesis_supply: u64,
}

/// Information about the total supply after V1_8 activation
Expand Down
124 changes: 63 additions & 61 deletions node/src/actors/chain_manager/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ use witnet_data_structures::{
};
use witnet_util::timestamp::get_timestamp;
use witnet_validations::validations::{
block_reward, total_block_reward, validate_rad_request, validate_stake_transaction,
validate_unstake_transaction,
validate_rad_request, validate_stake_transaction, validate_unstake_transaction,
};

use crate::{
Expand Down Expand Up @@ -1996,69 +1995,54 @@ impl Handler<GetSupplyInfo> for ChainManager {
}

let chain_info = self.chain_state.chain_info.as_ref().unwrap();
let halving_period = chain_info.consensus_constants.halving_period;
let initial_block_reward = chain_info.consensus_constants.initial_block_reward;
let collateral_minimum = chain_info.consensus_constants.collateral_minimum;

let current_epoch = self.current_epoch.unwrap();
let current_time = u64::try_from(get_timestamp()).unwrap();
let current_staked_supply = self.chain_state.stakes.total_staked().nanowits();

let mut current_unlocked_supply = 0;
let mut current_locked_supply = 0;
for (_output_pointer, value_transfer_output) in self.chain_state.unspent_outputs_pool.iter()
{
if value_transfer_output.0.time_lock <= current_time {
current_unlocked_supply += value_transfer_output.0.value;
} else {
current_locked_supply += value_transfer_output.0.value;
}
}
let wit1_block_reward = chain_info.consensus_constants.initial_block_reward;
let wit2_activation_epoch = get_protocol_version_activation_epoch(ProtocolVersion::V2_0);
let wit2_block_reward =
ConsensusConstantsWit2::default().get_validator_block_reward(current_epoch);

let in_flight_requests = self
.chain_state
.data_request_pool
.data_request_pool
.len()
.try_into()
.unwrap();
let locked_wits_by_requests = self
.chain_state
.data_request_pool
.locked_wits_by_requests(collateral_minimum);
let (mut blocks_minted, mut blocks_minted_reward) =
(self.last_blocks_minted, self.last_blocks_minted_reward);

let (mut blocks_minted, mut blocks_minted_reward) = (0, 0);
let (mut blocks_missing, mut blocks_missing_reward) = (0, 0);
for epoch in 1..current_epoch {
let block_reward = block_reward(epoch, initial_block_reward, halving_period);
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += block_reward;
// Otherwise, a block was rolled back or no block was proposed, add the reward to blocks_missing_reward
} else {
blocks_missing += 1;
blocks_missing_reward += block_reward;
if self.last_supply_info_epoch < wit2_activation_epoch {
for epoch in self.last_supply_info_epoch..wit2_activation_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit1_block_reward;
}
}
for epoch in wit2_activation_epoch..current_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit2_block_reward;
}
}
} else {
for epoch in self.last_supply_info_epoch..current_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit2_block_reward;
}
}
}

let genesis_amount =
current_locked_supply + current_unlocked_supply + locked_wits_by_requests
- blocks_minted_reward;
let maximum_block_reward = total_block_reward(initial_block_reward, halving_period);
let maximum_supply = genesis_amount + maximum_block_reward;
self.last_supply_info_epoch = current_epoch;
self.last_blocks_minted = blocks_minted;
self.last_blocks_minted_reward = blocks_minted_reward;

Ok(SupplyInfo {
epoch: current_epoch,
current_time,
blocks_minted,
blocks_minted_reward,
blocks_missing,
blocks_missing_reward,
in_flight_requests,
locked_wits_by_requests,
current_unlocked_supply,
current_locked_supply,
maximum_supply,
current_staked_supply,
genesis_supply: self.initial_supply,
})
}
}
Expand All @@ -2080,7 +2064,6 @@ impl Handler<GetSupplyInfo2> for ChainManager {
let current_staked_supply = self.chain_state.stakes.total_staked().nanowits();

let wit1_block_reward = chain_info.consensus_constants.initial_block_reward;
let wit2_activated = get_protocol_version(None) == ProtocolVersion::V2_0;
let wit2_activation_epoch = get_protocol_version_activation_epoch(ProtocolVersion::V2_0);
let wit2_block_reward =
ConsensusConstantsWit2::default().get_validator_block_reward(current_epoch);
Expand All @@ -2103,19 +2086,38 @@ impl Handler<GetSupplyInfo2> for ChainManager {
}
}

let (mut blocks_minted, mut blocks_minted_reward) = (0, 0);
for epoch in 1..current_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += if wit2_activated && epoch >= wit2_activation_epoch {
wit2_block_reward
} else {
wit1_block_reward
let (mut blocks_minted, mut blocks_minted_reward) =
(self.last_blocks_minted, self.last_blocks_minted_reward);

if self.last_supply_info_epoch < wit2_activation_epoch {
for epoch in self.last_supply_info_epoch..wit2_activation_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit1_block_reward;
}
}
for epoch in wit2_activation_epoch..current_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit2_block_reward;
}
}
} else {
for epoch in self.last_supply_info_epoch..current_epoch {
// If the blockchain contains an epoch, a block was minted in that epoch, add the reward to blocks_minted_reward
if self.chain_state.block_chain.contains_key(&epoch) {
blocks_minted += 1;
blocks_minted_reward += wit2_block_reward;
}
}
}

self.last_supply_info_epoch = current_epoch;
self.last_blocks_minted = blocks_minted;
self.last_blocks_minted_reward = blocks_minted_reward;

let burnt_supply = self
.initial_supply
.saturating_add(blocks_minted_reward)
Expand Down
6 changes: 6 additions & 0 deletions node/src/actors/chain_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ pub struct ChainManager {
initial_supply: u64,
/// Populate RAD hashes index
rad_hashes_index: bool,
/// Epoch when getSupplyInfo2 was last resolved.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose these variables are not saved to storage (and we do not need storage migrations)? That does imply whenever a node restarts (after a manual intervention or crash), this call will be slow again for the first time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed.

last_supply_info_epoch: u32,
/// Count of minted blocks the last time getSupplyInfo2 was resolved.
last_blocks_minted: u32,
/// Counf of minted rewards the last time getSupplyInfo2 was resolved.
last_blocks_minted_reward: u64,
}

impl ChainManager {
Expand Down
13 changes: 8 additions & 5 deletions node/src/actors/json_rpc/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,6 @@ pub fn attach_regular_methods<H>(
server.add_actix_method(system, "getSupplyInfo", |_params: Params| {
Box::pin(get_supply_info())
});
server.add_actix_method(system, "getSupplyInfo2", |_params: Params| {
Box::pin(get_supply_info_2())
});
server.add_actix_method(system, "peers", |_params: Params| Box::pin(peers()));
server.add_actix_method(system, "knownPeers", |_params: Params| {
Box::pin(known_peers())
Expand Down Expand Up @@ -300,7 +297,6 @@ pub fn attach_sensitive_methods<H>(
|params| stake(params.parse()),
))
});

server.add_actix_method(system, "authorizeStake", move |params: Params| {
Box::pin(if_authorized(
enable_sensitive_methods,
Expand All @@ -309,7 +305,6 @@ pub fn attach_sensitive_methods<H>(
|params| authorize_stake(params.parse()),
))
});

server.add_actix_method(system, "unstake", move |params| {
Box::pin(if_authorized(
enable_sensitive_methods,
Expand All @@ -318,6 +313,14 @@ pub fn attach_sensitive_methods<H>(
|params| unstake(params.parse()),
))
});
server.add_actix_method(system, "getSupplyInfo2", move |params| {
Box::pin(if_authorized(
enable_sensitive_methods,
"getSupplyInfo2",
params,
|_params| get_supply_info_2(),
))
});
}

fn extract_topic_and_params(params: Params) -> Result<(String, Value), Error> {
Expand Down
Loading
Loading