Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ members = [
"modules/parameters_state", # Keeps track of protocol parameters
"modules/governance_state", # Governance state
"modules/stake_delta_filter", # Filters address deltas
"modules/epoch_activity_counter", # Counts fees and block producers for rewards
"modules/epochs_state", # Tracks fees and blocks minted and epochs history
"modules/accounts_state", # Tracks stake and reward accounts
"modules/assets_state", # Tracks native asset mints and burns

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ structure is highly subject to change:
* [DRep State](modules/drep_state) - tracks DRep registrations
* [Governance State](modules/governance_state) - tracks Governance Actions and voting
* [Stake Delta Filter](modules/stake_delta_filter) - filters out stake address changes and handles stake pointer references
* [Epoch Activity Counter](modules/epoch_activity_counter) - counts fees and block production for rewards
* [Epochs State](modules/epochs_state) - track fees blocks minted and epochs history
* [Accounts State](modules/accounts_state) - stake and reward accounts tracker

```mermaid
Expand All @@ -74,24 +74,24 @@ graph LR
DRepState(DRep State)
GovernanceState(Governance State)
StakeDeltaFilter(Stake Delta Filter)
EpochActivityCounter(Epoch Activity Counter)
EpochsState(EpochsState)
AccountsState(Accounts State)

UpstreamChainFetcher --> BlockUnpacker
MithrilSnapshotFetcher --> BlockUnpacker
BlockUnpacker --> TxUnpacker
GenesisBootstrapper --> UTXOState
TxUnpacker --> UTXOState
TxUnpacker --> EpochActivityCounter
TxUnpacker --> EpochsState
TxUnpacker --> AccountsState
TxUnpacker --> SPOState
TxUnpacker --> DRepState
TxUnpacker --> GovernanceState
UTXOState --> StakeDeltaFilter
StakeDeltaFilter --> AccountsState
UpstreamChainFetcher --> EpochActivityCounter
MithrilSnapshotFetcher --> EpochActivityCounter
EpochActivityCounter --> AccountsState
UpstreamChainFetcher --> EpochsState
MithrilSnapshotFetcher --> EpochsState
EpochsState --> AccountsState
SPOState --> AccountsState
DRepState --> GovernanceState
GovernanceState --> AccountsState
Expand Down
21 changes: 21 additions & 0 deletions common/src/queries/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ pub enum AccountsStateQuery {
GetAccountAssets { stake_key: Vec<u8> },
GetAccountAssetsTotals { stake_key: Vec<u8> },
GetAccountUTxOs { stake_key: Vec<u8> },
GetAccountsUtxoValuesMap { stake_keys: Vec<Vec<u8>> },
GetAccountsUtxoValuesSum { stake_keys: Vec<Vec<u8>> },
GetAccountsBalancesMap { stake_keys: Vec<Vec<u8>> },
GetAccountsBalancesSum { stake_keys: Vec<Vec<u8>> },

// Pools related queries
GetOptimalPoolSizing,
GetPoolsLiveStakes { pools_operators: Vec<Vec<u8>> },
GetPoolDelegators { pool_operator: KeyHash },
GetPoolLiveStakeInfo { pool_operator: KeyHash },

// Dreps related queries
GetAccountsDrepDelegationsMap { stake_keys: Vec<Vec<u8>> },
Expand All @@ -42,12 +46,16 @@ pub enum AccountsStateQueryResponse {
AccountAssets(AccountAssets),
AccountAssetsTotals(AccountAssetsTotals),
AccountUTxOs(AccountUTxOs),
AccountsUtxoValuesMap(HashMap<Vec<u8>, u64>),
AccountsUtxoValuesSum(u64),
AccountsBalancesMap(HashMap<Vec<u8>, u64>),
AccountsBalancesSum(u64),

// Pools related responses
OptimalPoolSizing(OptimalPoolSizing),
PoolsLiveStakes(PoolsLiveStakes),
PoolDelegators(PoolDelegators),
PoolLiveStakeInfo(PoolLiveStakeInfo),

// DReps related responses
AccountsDrepDelegationsMap(HashMap<Vec<u8>, Option<DRepChoice>>),
Expand Down Expand Up @@ -94,6 +102,12 @@ pub struct AccountAssetsTotals {}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct AccountUTxOs {}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct OptimalPoolSizing {
pub total_supply: u64, // total_supply - reserves
pub nopt: u64,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolsLiveStakes {
// this is in same order of pools_operator from AccountsStateQuery::GetPoolsLiveStakes
Expand All @@ -104,3 +118,10 @@ pub struct PoolsLiveStakes {
pub struct PoolDelegators {
pub delegators: Vec<(KeyHash, u64)>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolLiveStakeInfo {
pub live_stake: u64,
pub live_delegators: u64,
pub total_live_stakes: u64,
}
17 changes: 16 additions & 1 deletion common/src/queries/epochs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{messages::EpochActivityMessage, protocol_params::ProtocolParams, KeyHash};
use crate::{messages::EpochActivityMessage, protocol_params::ProtocolParams, BlockHash, KeyHash};

pub const DEFAULT_EPOCHS_QUERY_TOPIC: (&str, &str) =
("epochs-state-query-topic", "cardano.query.epochs");
Expand All @@ -17,6 +17,8 @@ pub enum EpochsStateQuery {
// Pools related queries
GetBlocksMintedByPools { vrf_key_hashes: Vec<KeyHash> },
GetTotalBlocksMintedByPools { vrf_key_hashes: Vec<KeyHash> },
GetBlocksMintedInfoByPool { vrf_key_hash: KeyHash },
GetBlockHashesByPool { vrf_key_hash: KeyHash },
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
Expand All @@ -33,6 +35,8 @@ pub enum EpochsStateQueryResponse {
// Pools related responses
BlocksMintedByPools(BlocksMintedByPools),
TotalBlocksMintedByPools(TotalBlocksMintedByPools),
BlocksMintedInfoByPool(BlocksMintedInfoByPool),
BlockHashesByPool(BlockHashesByPool),

NotFound,
Error(String),
Expand Down Expand Up @@ -82,3 +86,14 @@ pub struct TotalBlocksMintedByPools {
// this is in same order of vrf_key_hashes from EpochsStateQuery::TotalBlocksMinted
pub total_blocks_minted: Vec<u64>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BlocksMintedInfoByPool {
pub total_blocks_minted: u64,
pub epoch_blocks_minted: u64,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BlockHashesByPool {
pub hashes: Vec<BlockHash>,
}
4 changes: 4 additions & 0 deletions common/src/queries/governance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::collections::HashMap;

use serde_with::{hex::Hex, serde_as};

use crate::{
Anchor, Credential, DRepCredential, GovActionId, Lovelace, ProposalProcedure, TxHash, Vote,
Voter, VotingProcedure,
Expand Down Expand Up @@ -93,8 +95,10 @@ pub struct DRepVotes {
pub votes: Vec<VoteRecord>,
}

#[serde_as]
#[derive(Clone, serde::Serialize, serde::Deserialize, Debug)]
pub struct VoteRecord {
#[serde_as(as = "Hex")]
pub tx_hash: TxHash,
pub vote_index: u32,
pub vote: Vote,
Expand Down
38 changes: 22 additions & 16 deletions common/src/queries/pools.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{KeyHash, PoolEpochState, PoolMetadata, PoolRegistration, PoolRetirement, Relay};
use crate::{
queries::governance::VoteRecord, rational_number::RationalNumber, KeyHash, PoolEpochState,
PoolMetadata, PoolRegistration, PoolRetirement, PoolUpdateEvent, Relay,
};

pub const DEFAULT_POOLS_QUERY_TOPIC: (&str, &str) =
("pools-state-query-topic", "cardano.query.pools");
Expand All @@ -9,6 +12,10 @@ pub enum PoolsStateQuery {
GetPoolsListWithInfo,
GetPoolsRetiredList,
GetPoolsRetiringList,
GetPoolActiveStakeInfo {
pool_operator: KeyHash,
epoch: u64,
},
GetPoolsActiveStakes {
pools_operators: Vec<Vec<u8>>,
epoch: u64,
Expand All @@ -28,9 +35,6 @@ pub enum PoolsStateQuery {
GetPoolDelegators {
pool_id: Vec<u8>,
},
GetPoolBlocks {
pool_id: Vec<u8>,
},
GetPoolUpdates {
pool_id: Vec<u8>,
},
Expand All @@ -45,13 +49,13 @@ pub enum PoolsStateQueryResponse {
PoolsListWithInfo(PoolsListWithInfo),
PoolsRetiredList(PoolsRetiredList),
PoolsRetiringList(PoolsRetiringList),
PoolActiveStakeInfo(PoolActiveStakeInfo),
PoolsActiveStakes(PoolsActiveStakes),
PoolInfo(PoolInfo),
PoolInfo(PoolRegistration),
PoolHistory(PoolHistory),
PoolMetadata(PoolMetadata),
PoolRelays(PoolRelays),
PoolDelegators(PoolDelegators),
PoolBlocks(PoolBlocks),
PoolUpdates(PoolUpdates),
PoolVotes(PoolVotes),
NotFound,
Expand Down Expand Up @@ -79,17 +83,18 @@ pub struct PoolsRetiringList {
pub retiring_pools: Vec<PoolRetirement>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolActiveStakeInfo {
pub active_stake: u64,
pub active_size: RationalNumber,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolsActiveStakes {
// this is in same order of pools_operator from PoolsStateQuery::GetPoolsActiveStakes
pub active_stakes: Vec<u64>,
// this is total active stake for current epoch
pub total_active_stake: u64,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolInfo {}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolHistory {
pub history: Vec<PoolEpochState>,
Expand All @@ -105,10 +110,11 @@ pub struct PoolDelegators {
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolBlocks {}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolUpdates {}
pub struct PoolUpdates {
pub updates: Vec<PoolUpdateEvent>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolVotes {}
pub struct PoolVotes {
pub votes: Vec<VoteRecord>,
}
61 changes: 57 additions & 4 deletions common/src/stake_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use std::{
};

use crate::{
math::update_value_with_delta, messages::DRepDelegationDistribution, DRepChoice,
DRepCredential, DelegatedStake, KeyHash, Lovelace, StakeAddressDelta, StakeCredential,
Withdrawal,
math::update_value_with_delta, messages::DRepDelegationDistribution,
queries::accounts::PoolLiveStakeInfo, DRepChoice, DRepCredential, DelegatedStake, KeyHash,
Lovelace, StakeAddressDelta, StakeCredential, Withdrawal,
};
use anyhow::Result;
use dashmap::DashMap;
Expand Down Expand Up @@ -110,6 +110,31 @@ impl StakeAddressMap {
self.get(stake_key).map(|sas| sas.registered).unwrap_or(false)
}

/// Get Pool's Live Stake Info
pub fn get_pool_live_stake_info(&self, spo: &KeyHash) -> PoolLiveStakeInfo {
let total_live_stakes = AtomicU64::new(0);
let live_stake = AtomicU64::new(0);
let live_delegators = AtomicU64::new(0);

// Par Iter stake addresses values
self.inner.par_iter().for_each(|(_, sas)| {
total_live_stakes.fetch_add(sas.utxo_value, std::sync::atomic::Ordering::Relaxed);
if sas.delegated_spo.as_ref().map(|d_spo| d_spo.eq(spo)).unwrap_or(false) {
live_stake.fetch_add(sas.utxo_value, std::sync::atomic::Ordering::Relaxed);
live_delegators.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
});

let total_live_stakes = total_live_stakes.load(std::sync::atomic::Ordering::Relaxed);
let live_stake = live_stake.load(std::sync::atomic::Ordering::Relaxed);
let live_delegators = live_delegators.load(std::sync::atomic::Ordering::Relaxed);
PoolLiveStakeInfo {
live_stake,
live_delegators,
total_live_stakes,
}
}

/// Get Pool's Live Stake (same order as spos)
pub fn get_pools_live_stakes(&self, spos: &Vec<KeyHash>) -> Vec<u64> {
let mut live_stakes_map = HashMap::<KeyHash, u64>::new();
Expand Down Expand Up @@ -142,7 +167,7 @@ impl StakeAddressMap {
.filter_map(|(stake_key, sas)| match sas.delegated_spo.as_ref() {
Some(delegated_spo) => {
if delegated_spo.eq(pool_operator) {
Some((stake_key.clone(), sas.utxo_value + sas.rewards))
Some((stake_key.clone(), sas.utxo_value))
} else {
None
}
Expand All @@ -154,6 +179,23 @@ impl StakeAddressMap {
delegators
}

/// Map stake_keys to their utxo_value
/// Return None if any of the stake_keys are not found
pub fn get_accounts_utxo_values_map(
&self,
stake_keys: &[Vec<u8>],
) -> Option<HashMap<Vec<u8>, u64>> {
let mut map = HashMap::new();

for key in stake_keys {
let account = self.get(key)?;
let utxo_value = account.utxo_value;
map.insert(key.clone(), utxo_value);
}

Some(map)
}

/// Map stake_keys to their total balances (utxo + rewards)
/// Return None if any of the stake_keys are not found
pub fn get_accounts_balances_map(
Expand Down Expand Up @@ -188,6 +230,17 @@ impl StakeAddressMap {
Some(map)
}

/// Sum stake_keys utxo_values
/// Return None if any of the stake_keys are not found
pub fn get_accounts_utxo_values_sum(&self, stake_keys: &[Vec<u8>]) -> Option<u64> {
let mut total = 0;
for key in stake_keys {
let account = self.get(key)?;
total += account.utxo_value;
}
Some(total)
}

/// Sum stake_keys balances (utxo + rewards)
/// Return None if any of stake_keys are not found
pub fn get_account_balances_sum(&self, stake_keys: &[Vec<u8>]) -> Option<u64> {
Expand Down
Loading