Merge pull request #4346 from nymtech/feature/rewarder-whitelist
Feature/rewarder whitelist
This commit is contained in:
@@ -27,6 +27,7 @@ CREATE TABLE block_signing_reward
|
||||
rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id),
|
||||
validator_consensus_address TEXT NOT NULL,
|
||||
operator_account TEXT NOT NULL,
|
||||
whitelisted BOOLEAN NOT NULL,
|
||||
amount TEXT NOT NULL,
|
||||
voting_power BIGINT NOT NULL,
|
||||
voting_power_share TEXT NOT NULL,
|
||||
@@ -38,11 +39,11 @@ CREATE TABLE block_signing_reward
|
||||
|
||||
CREATE TABLE epoch_credential_issuance
|
||||
(
|
||||
rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id),
|
||||
starting_dkg_epoch INTEGER NOT NULL,
|
||||
ending_dkg_epoch INTEGER NOT NULL,
|
||||
rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id),
|
||||
starting_dkg_epoch INTEGER NOT NULL,
|
||||
ending_dkg_epoch INTEGER NOT NULL,
|
||||
total_issued_partial_credentials INTEGER NOT NULL,
|
||||
budget TEXT NOT NULL
|
||||
budget TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE malformed_credential
|
||||
@@ -56,6 +57,7 @@ CREATE TABLE credential_issuance_reward
|
||||
rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id),
|
||||
operator_account TEXT NOT NULL,
|
||||
amount TEXT NOT NULL,
|
||||
whitelisted BOOLEAN NOT NULL,
|
||||
api_endpoint TEXT NOT NULL,
|
||||
issued_partial_credentials INTEGER NOT NULL,
|
||||
issued_credentials_share TEXT NOT NULL,
|
||||
|
||||
@@ -9,7 +9,7 @@ use nym_config::{
|
||||
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
|
||||
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
|
||||
};
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
use nym_validator_client::nyxd::{AccountId, Coin};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
use std::io;
|
||||
@@ -225,7 +225,7 @@ impl Default for RewardingRatios {
|
||||
impl RewardingRatios {
|
||||
pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> {
|
||||
if self.block_signing + self.credential_verification + self.credential_issuance != 1.0 {
|
||||
todo!()
|
||||
return Err(NymRewarderError::InvalidRewardingRatios { ratios: *self });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -238,19 +238,26 @@ pub struct NyxdScraper {
|
||||
// TODO: debug with everything that's currently hardcoded in the scraper
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Copy)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct BlockSigning {
|
||||
/// Specifies whether credential issuance for block signing is enabled.
|
||||
pub enabled: bool,
|
||||
|
||||
/// List of validators that will receive rewards for block signing.
|
||||
/// If not on the list, the validator will be treated as if it had 0 voting power.
|
||||
pub whitelist: Vec<AccountId>,
|
||||
}
|
||||
|
||||
impl Default for BlockSigning {
|
||||
fn default() -> Self {
|
||||
BlockSigning { enabled: true }
|
||||
BlockSigning {
|
||||
enabled: true,
|
||||
whitelist: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Copy)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IssuanceMonitor {
|
||||
/// Specifies whether credential issuance monitoring (and associated rewards) are enabled.
|
||||
pub enabled: bool,
|
||||
@@ -264,15 +271,20 @@ pub struct IssuanceMonitor {
|
||||
|
||||
/// The sampling rate of the issued credentials
|
||||
pub sampling_rate: f64,
|
||||
|
||||
/// List of validators that will receive rewards for credential issuance.
|
||||
/// If not on the list, the validator will be treated as if it hadn't issued a single credential.
|
||||
pub whitelist: Vec<AccountId>,
|
||||
}
|
||||
|
||||
impl Default for IssuanceMonitor {
|
||||
fn default() -> Self {
|
||||
IssuanceMonitor {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
run_interval: DEFAULT_MONITOR_RUN_INTERVAL,
|
||||
min_validate_per_issuer: DEFAULT_MONITOR_MIN_VALIDATE,
|
||||
sampling_rate: DEFAULT_MONITOR_SAMPLING_RATE,
|
||||
whitelist: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,14 @@ credential_verification = {{ rewarding.ratios.credential_verification }}
|
||||
[block_signing]
|
||||
# Specifies whether credential issuance for block signing is enabled.
|
||||
enabled = {{ block_signing.enabled }}
|
||||
|
||||
|
||||
# List of validators that will receive rewards for block signing.
|
||||
# If not on the list, the validator will be treated as if it had 0 voting power.
|
||||
whitelist = [
|
||||
# needs to be manually populated; expects nvalcons1... addresses.
|
||||
# you can get them from, for example, `/cosmos/base/tendermint/v1beta1/validatorsets/latest` endpoint
|
||||
]
|
||||
|
||||
|
||||
[issuance_monitor]
|
||||
# Specifies whether credential issuance monitoring (and associated rewards) are enabled.
|
||||
@@ -54,6 +61,12 @@ min_validate_per_issuer = {{ issuance_monitor.min_validate_per_issuer }}
|
||||
|
||||
# The sampling rate of the issued credentials
|
||||
sampling_rate = {{ issuance_monitor.sampling_rate }}
|
||||
|
||||
# List of validators that will receive rewards for credential issuance.
|
||||
# If not on the list, the validator will be treated as if it hadn't issued a single credential.
|
||||
whitelist = [
|
||||
# needs to be manually populated; expects n1... addresses
|
||||
]
|
||||
|
||||
[nyxd_scraper]
|
||||
# Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::config::RewardingRatios;
|
||||
use nym_coconut::CoconutError;
|
||||
use nym_validator_client::nym_api::error::NymAPIError;
|
||||
use nym_validator_client::nyxd::error::NyxdError;
|
||||
@@ -50,7 +51,7 @@ pub enum NymRewarderError {
|
||||
NyxdFailure(#[from] NyxdError),
|
||||
|
||||
#[error("the provided rewarding ratios don't add up to 1. ratios: {ratios:?}")]
|
||||
InvalidRewardingRatios { ratios: Vec<f32> },
|
||||
InvalidRewardingRatios { ratios: RewardingRatios },
|
||||
|
||||
#[error("chain scraping failure: {source}")]
|
||||
ScraperFailure {
|
||||
@@ -156,6 +157,12 @@ pub enum NymRewarderError {
|
||||
|
||||
#[error("the scraper websocket endpoint hasn't been provided")]
|
||||
UnavailableWebsocketUrl,
|
||||
|
||||
#[error("block signing rewarding is enabled, but the validator whitelist is empty")]
|
||||
EmptyBlockSigningWhitelist,
|
||||
|
||||
#[error("credential issuance rewarding is enabled, but the validator whitelist is empty")]
|
||||
EmptyCredentialIssuanceWhitelist,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#![warn(clippy::expect_used)]
|
||||
#![warn(clippy::unwrap_used)]
|
||||
#![warn(clippy::todo)]
|
||||
#![warn(clippy::dbg_macro)]
|
||||
|
||||
use crate::cli::Cli;
|
||||
use clap::{crate_name, crate_version, Parser};
|
||||
|
||||
@@ -6,18 +6,19 @@ use crate::rewarder::block_signing::types::{EpochSigningResults, RawValidatorRes
|
||||
use crate::rewarder::epoch::Epoch;
|
||||
use crate::rewarder::nyxd_client::NyxdClient;
|
||||
use nym_validator_client::nyxd::module_traits::staking;
|
||||
use nym_validator_client::nyxd::PageRequest;
|
||||
use nym_validator_client::nyxd::{AccountId, PageRequest};
|
||||
use nyxd_scraper::NyxdScraper;
|
||||
use std::cmp::min;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use tracing::info;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
pub(crate) mod types;
|
||||
|
||||
pub struct EpochSigning {
|
||||
pub(crate) nyxd_client: NyxdClient,
|
||||
pub(crate) nyxd_scraper: NyxdScraper,
|
||||
pub(crate) whitelist: Vec<AccountId>,
|
||||
}
|
||||
|
||||
impl EpochSigning {
|
||||
@@ -116,14 +117,29 @@ impl EpochSigning {
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
total_vp += vp;
|
||||
|
||||
let cons_address = &validator.consensus_address;
|
||||
// if this validator is NOT whitelisted, do not increase the total VP
|
||||
let whitelisted = if let Ok(parsed) = cons_address.parse() {
|
||||
if self.whitelist.contains(&parsed) {
|
||||
debug!("{cons_address} is on the whitelist");
|
||||
total_vp += vp;
|
||||
true
|
||||
} else {
|
||||
warn!("{cons_address} is not a valid consensus address");
|
||||
false
|
||||
}
|
||||
} else {
|
||||
debug!("{cons_address} is not on the whitelist");
|
||||
false
|
||||
};
|
||||
|
||||
let signed = self
|
||||
.nyxd_scraper
|
||||
.storage
|
||||
.get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end)
|
||||
.await?;
|
||||
signed_in_epoch.insert(validator, RawValidatorResult::new(signed, vp));
|
||||
signed_in_epoch.insert(validator, RawValidatorResult::new(signed, vp, whitelisted));
|
||||
}
|
||||
|
||||
let total = self
|
||||
|
||||
@@ -15,6 +15,7 @@ pub struct ValidatorSigning {
|
||||
pub validator: models::Validator,
|
||||
pub staking_details: staking::Validator,
|
||||
pub operator_account: AccountId,
|
||||
pub whitelisted: bool,
|
||||
|
||||
pub voting_power_at_epoch_start: i64,
|
||||
pub voting_power_ratio: Decimal,
|
||||
@@ -33,6 +34,10 @@ impl ValidatorSigning {
|
||||
}
|
||||
|
||||
pub fn reward_amount(&self, signing_budget: &Coin) -> Coin {
|
||||
if !self.whitelisted {
|
||||
return Coin::new(0, &signing_budget.denom);
|
||||
}
|
||||
|
||||
let amount =
|
||||
Uint128::new(signing_budget.amount) * self.ratio_signed * self.voting_power_ratio;
|
||||
|
||||
@@ -51,13 +56,15 @@ pub struct EpochSigningResults {
|
||||
pub struct RawValidatorResult {
|
||||
pub signed_blocks: i32,
|
||||
pub voting_power: i64,
|
||||
pub whitelisted: bool,
|
||||
}
|
||||
|
||||
impl RawValidatorResult {
|
||||
pub fn new(signed_blocks: i32, voting_power: i64) -> Self {
|
||||
pub fn new(signed_blocks: i32, voting_power: i64, whitelisted: bool) -> Self {
|
||||
Self {
|
||||
signed_blocks,
|
||||
voting_power,
|
||||
whitelisted,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +100,11 @@ impl EpochSigningResults {
|
||||
let vp: u64 = raw_results.voting_power.try_into().unwrap_or_default();
|
||||
let signed: u64 = raw_results.signed_blocks.try_into().unwrap_or_default();
|
||||
|
||||
let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64);
|
||||
let voting_power_ratio = if raw_results.whitelisted {
|
||||
Decimal::from_ratio(vp, total_vp_u64)
|
||||
} else {
|
||||
Decimal::zero()
|
||||
};
|
||||
|
||||
debug_assert!(signed <= blocks_u64);
|
||||
let ratio_signed = Decimal::from_ratio(signed, blocks_u64);
|
||||
@@ -110,6 +121,7 @@ impl EpochSigningResults {
|
||||
validator,
|
||||
staking_details,
|
||||
operator_account,
|
||||
whitelisted: raw_results.whitelisted,
|
||||
voting_power_at_epoch_start: raw_results.voting_power,
|
||||
voting_power_ratio,
|
||||
signed_blocks: raw_results.signed_blocks,
|
||||
@@ -129,10 +141,11 @@ impl EpochSigningResults {
|
||||
.iter()
|
||||
.inspect(|v| {
|
||||
info!(
|
||||
"validator {} will receive {} at address {} for block signing work",
|
||||
"validator {} will receive {} at address {} for block signing work (whitelisted: {})",
|
||||
v.moniker(),
|
||||
v.reward_amount(budget),
|
||||
v.operator_account
|
||||
v.operator_account,
|
||||
v.whitelisted
|
||||
);
|
||||
})
|
||||
.map(|v| (v.operator_account.clone(), vec![v.reward_amount(budget)]))
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::rewarder::credential_issuance::types::{CredentialIssuanceResults, Mon
|
||||
use crate::rewarder::epoch::Epoch;
|
||||
use crate::rewarder::nyxd_client::NyxdClient;
|
||||
use nym_task::TaskClient;
|
||||
use nym_validator_client::nyxd::AccountId;
|
||||
use tracing::info;
|
||||
|
||||
mod monitor;
|
||||
@@ -21,9 +22,11 @@ impl CredentialIssuance {
|
||||
pub(crate) async fn new(
|
||||
epoch: Epoch,
|
||||
nyxd_client: &NyxdClient,
|
||||
whitelist: &[AccountId],
|
||||
) -> Result<Self, NymRewarderError> {
|
||||
Ok(CredentialIssuance {
|
||||
monitoring_results: MonitoringResults::new_initial(epoch, nyxd_client).await?,
|
||||
monitoring_results: MonitoringResults::new_initial(epoch, nyxd_client, whitelist)
|
||||
.await?,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -235,12 +235,15 @@ impl CredentialIssuanceMonitor {
|
||||
let api_client = api_client(&issuer)?;
|
||||
|
||||
let epoch_credentials = api_client.epoch_credentials(epoch_id).await?;
|
||||
let whitelisted = self.config.whitelist.contains(&issuer.operator_account);
|
||||
|
||||
let Some(first_id) = epoch_credentials.first_epoch_credential_id else {
|
||||
// no point in doing anything more - if they haven't issued anything, there's nothing to verify
|
||||
debug!("no credentials issued this epoch",);
|
||||
return Ok(RawOperatorResult::new_empty(
|
||||
issuer.operator_account,
|
||||
issuer.api_runner,
|
||||
whitelisted,
|
||||
));
|
||||
};
|
||||
trace!("issued credentials: {epoch_credentials:?}");
|
||||
@@ -283,6 +286,7 @@ impl CredentialIssuanceMonitor {
|
||||
Ok(RawOperatorResult {
|
||||
operator_account: issuer.operator_account,
|
||||
api_runner: issuer.api_runner,
|
||||
whitelisted,
|
||||
issued_credentials: epoch_credentials.total_issued,
|
||||
validated_credentials: sampled,
|
||||
})
|
||||
|
||||
@@ -25,6 +25,7 @@ impl MonitoringResults {
|
||||
pub(crate) async fn new_initial(
|
||||
initial_epoch: Epoch,
|
||||
nyxd_client: &NyxdClient,
|
||||
whitelist: &[AccountId],
|
||||
) -> Result<Self, NymRewarderError> {
|
||||
let epoch = nyxd_client.dkg_epoch().await?;
|
||||
let issuers = nyxd_client.get_credential_issuers(epoch.epoch_id).await?;
|
||||
@@ -36,6 +37,7 @@ impl MonitoringResults {
|
||||
let mut raw_issuer = RawOperatorIssuing {
|
||||
api_runner: issuer.api_runner.clone(),
|
||||
runner_account: issuer.operator_account.clone(),
|
||||
whitelisted: whitelist.contains(&issuer.operator_account),
|
||||
per_epoch: Default::default(),
|
||||
};
|
||||
|
||||
@@ -132,6 +134,7 @@ impl MonitoringResults {
|
||||
RawOperatorIssuing {
|
||||
api_runner: result.api_runner.clone(),
|
||||
runner_account: result.runner_account.clone(),
|
||||
whitelisted: result.whitelisted,
|
||||
per_epoch: kept_epoch,
|
||||
},
|
||||
);
|
||||
@@ -157,18 +160,20 @@ pub(crate) struct MonitoringResultsInner {
|
||||
|
||||
impl From<MonitoringResultsInner> for CredentialIssuanceResults {
|
||||
fn from(value: MonitoringResultsInner) -> Self {
|
||||
let total_issued = value
|
||||
.operators
|
||||
.values()
|
||||
.map(|o| {
|
||||
let operator_issued: u32 = o
|
||||
let mut total_issued = 0;
|
||||
|
||||
for operator in value.operators.values() {
|
||||
// if this validator is NOT whitelisted, do not increase the total issued credentials
|
||||
if operator.whitelisted {
|
||||
let operator_issued: u32 = operator
|
||||
.per_epoch
|
||||
.values()
|
||||
.map(|e| e.issued_since_monitor_started)
|
||||
.sum();
|
||||
operator_issued
|
||||
})
|
||||
.sum();
|
||||
|
||||
total_issued += operator_issued
|
||||
}
|
||||
}
|
||||
|
||||
CredentialIssuanceResults {
|
||||
total_issued_partial_credentials: total_issued,
|
||||
@@ -177,7 +182,7 @@ impl From<MonitoringResultsInner> for CredentialIssuanceResults {
|
||||
.operators
|
||||
.into_values()
|
||||
.map(|runner| {
|
||||
let issued_ratio = if total_issued == 0 {
|
||||
let issued_ratio = if total_issued == 0 || !runner.whitelisted {
|
||||
Decimal::zero()
|
||||
} else {
|
||||
Decimal::from_ratio(runner.issued_credentials(), total_issued)
|
||||
@@ -187,6 +192,7 @@ impl From<MonitoringResultsInner> for CredentialIssuanceResults {
|
||||
issued_credentials: runner.issued_credentials(),
|
||||
validated_credentials: runner.validated_credentials(),
|
||||
api_runner: runner.api_runner,
|
||||
whitelisted: runner.whitelisted,
|
||||
runner_account: runner.runner_account,
|
||||
}
|
||||
})
|
||||
@@ -212,6 +218,7 @@ impl MonitoringResultsInner {
|
||||
pub(crate) struct RawOperatorResult {
|
||||
pub(crate) operator_account: AccountId,
|
||||
pub(crate) api_runner: String,
|
||||
pub(crate) whitelisted: bool,
|
||||
|
||||
// how many credentials the operator claims to have issued in **TOTAL** in this **DKG** epoch
|
||||
pub(crate) issued_credentials: u32,
|
||||
@@ -219,10 +226,15 @@ pub(crate) struct RawOperatorResult {
|
||||
}
|
||||
|
||||
impl RawOperatorResult {
|
||||
pub(crate) fn new_empty(operator_account: AccountId, api_runner: String) -> RawOperatorResult {
|
||||
pub(crate) fn new_empty(
|
||||
operator_account: AccountId,
|
||||
api_runner: String,
|
||||
whitelisted: bool,
|
||||
) -> RawOperatorResult {
|
||||
RawOperatorResult {
|
||||
operator_account,
|
||||
api_runner,
|
||||
whitelisted,
|
||||
issued_credentials: 0,
|
||||
validated_credentials: Default::default(),
|
||||
}
|
||||
@@ -232,6 +244,7 @@ impl RawOperatorResult {
|
||||
pub struct RawOperatorIssuing {
|
||||
pub api_runner: String,
|
||||
pub runner_account: AccountId,
|
||||
pub whitelisted: bool,
|
||||
|
||||
pub per_epoch: HashMap<u32, IssuedEpochCredentials>,
|
||||
}
|
||||
@@ -243,6 +256,7 @@ impl RawOperatorIssuing {
|
||||
RawOperatorIssuing {
|
||||
api_runner: raw_result.api_runner,
|
||||
runner_account: raw_result.operator_account,
|
||||
whitelisted: raw_result.whitelisted,
|
||||
per_epoch,
|
||||
}
|
||||
}
|
||||
@@ -278,6 +292,7 @@ impl IssuedEpochCredentials {
|
||||
|
||||
pub struct OperatorIssuing {
|
||||
pub api_runner: String,
|
||||
pub whitelisted: bool,
|
||||
pub runner_account: AccountId,
|
||||
|
||||
pub issued_ratio: Decimal,
|
||||
@@ -286,10 +301,14 @@ pub struct OperatorIssuing {
|
||||
}
|
||||
|
||||
impl OperatorIssuing {
|
||||
pub fn reward_amount(&self, signing_budget: &Coin) -> Coin {
|
||||
let amount = Uint128::new(signing_budget.amount) * self.issued_ratio;
|
||||
pub fn reward_amount(&self, issuance_budget: &Coin) -> Coin {
|
||||
if !self.whitelisted {
|
||||
return Coin::new(0, &issuance_budget.denom);
|
||||
}
|
||||
|
||||
Coin::new(amount.u128(), &signing_budget.denom)
|
||||
let amount = Uint128::new(issuance_budget.amount) * self.issued_ratio;
|
||||
|
||||
Coin::new(amount.u128(), &issuance_budget.denom)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,10 +324,11 @@ impl CredentialIssuanceResults {
|
||||
.iter()
|
||||
.inspect(|a| {
|
||||
info!(
|
||||
"operator {} will receive {} at address {} for credential issuance work",
|
||||
"operator {} will receive {} at address {} for credential issuance work (whitelisted: {})",
|
||||
a.api_runner,
|
||||
a.reward_amount(budget),
|
||||
a.runner_account,
|
||||
a.whitelisted
|
||||
);
|
||||
})
|
||||
.map(|v| (v.runner_account.clone(), vec![v.reward_amount(budget)]))
|
||||
|
||||
@@ -41,17 +41,19 @@ impl EpochRewards {
|
||||
let mut amounts = Vec::new();
|
||||
|
||||
if let Some(signing) = &self.signing {
|
||||
for signing_amount in signing.rewarding_amounts(&self.signing_budget) {
|
||||
if signing_amount.1[0].amount != 0 {
|
||||
amounts.push(signing_amount)
|
||||
for (account, signing_amount) in signing.rewarding_amounts(&self.signing_budget) {
|
||||
if signing_amount[0].amount != 0 {
|
||||
amounts.push((account, signing_amount))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(credentials) = &self.credentials {
|
||||
for credential_amount in credentials.rewarding_amounts(&self.credentials_budget) {
|
||||
if credential_amount.1[0].amount != 0 {
|
||||
amounts.push(credential_amount)
|
||||
for (account, credential_amount) in
|
||||
credentials.rewarding_amounts(&self.credentials_budget)
|
||||
{
|
||||
if credential_amount[0].amount != 0 {
|
||||
amounts.push((account, credential_amount))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,18 +88,29 @@ impl Rewarder {
|
||||
};
|
||||
|
||||
let epoch_signing = if config.block_signing.enabled {
|
||||
let whitelist = config.block_signing.whitelist.clone();
|
||||
if whitelist.is_empty() {
|
||||
return Err(NymRewarderError::EmptyBlockSigningWhitelist);
|
||||
}
|
||||
|
||||
let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?;
|
||||
|
||||
Some(EpochSigning {
|
||||
nyxd_scraper,
|
||||
nyxd_client: nyxd_client.clone(),
|
||||
whitelist,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let credential_issuance = if config.issuance_monitor.enabled {
|
||||
Some(CredentialIssuance::new(current_epoch, &nyxd_client).await?)
|
||||
let whitelist = &config.issuance_monitor.whitelist;
|
||||
if whitelist.is_empty() {
|
||||
return Err(NymRewarderError::EmptyCredentialIssuanceWhitelist);
|
||||
}
|
||||
|
||||
Some(CredentialIssuance::new(current_epoch, &nyxd_client, whitelist).await?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -239,7 +252,7 @@ impl Rewarder {
|
||||
|
||||
if let Some(ref credential_issuance) = self.credential_issuance {
|
||||
credential_issuance.start_monitor(
|
||||
self.config.issuance_monitor,
|
||||
self.config.issuance_monitor.clone(),
|
||||
self.nyxd_client.clone(),
|
||||
task_manager.subscribe(),
|
||||
);
|
||||
|
||||
@@ -74,6 +74,7 @@ impl StorageManager {
|
||||
epoch: i64,
|
||||
consensus_address: String,
|
||||
operator_account: String,
|
||||
whitelisted: bool,
|
||||
amount: String,
|
||||
voting_power: i64,
|
||||
voting_power_share: String,
|
||||
@@ -86,16 +87,18 @@ impl StorageManager {
|
||||
rewarding_epoch_id,
|
||||
validator_consensus_address,
|
||||
operator_account,
|
||||
whitelisted,
|
||||
amount,
|
||||
voting_power,
|
||||
voting_power_share,
|
||||
signed_blocks,
|
||||
signed_blocks_percent
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"#,
|
||||
epoch,
|
||||
consensus_address,
|
||||
operator_account,
|
||||
whitelisted,
|
||||
amount,
|
||||
voting_power,
|
||||
voting_power_share,
|
||||
@@ -144,6 +147,7 @@ impl StorageManager {
|
||||
&self,
|
||||
epoch: i64,
|
||||
operator_account: String,
|
||||
whitelisted: bool,
|
||||
amount: String,
|
||||
api_endpoint: String,
|
||||
issued_partial_credentials: u32,
|
||||
@@ -155,15 +159,17 @@ impl StorageManager {
|
||||
INSERT INTO credential_issuance_reward (
|
||||
rewarding_epoch_id,
|
||||
operator_account,
|
||||
whitelisted,
|
||||
amount,
|
||||
api_endpoint,
|
||||
issued_partial_credentials,
|
||||
issued_credentials_share,
|
||||
validated_issued_credentials
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"#,
|
||||
epoch,
|
||||
operator_account,
|
||||
whitelisted,
|
||||
amount,
|
||||
api_endpoint,
|
||||
issued_partial_credentials,
|
||||
|
||||
@@ -104,6 +104,7 @@ impl RewarderStorage {
|
||||
epoch_id,
|
||||
validator.validator.consensus_address,
|
||||
validator.operator_account.to_string(),
|
||||
validator.whitelisted,
|
||||
reward_amount,
|
||||
validator.voting_power_at_epoch_start,
|
||||
validator.voting_power_ratio.to_string(),
|
||||
@@ -152,6 +153,7 @@ impl RewarderStorage {
|
||||
.insert_rewarding_epoch_credential_issuance_reward(
|
||||
epoch_id,
|
||||
api_runner.runner_account.to_string(),
|
||||
api_runner.whitelisted,
|
||||
reward_amount,
|
||||
api_runner.api_runner,
|
||||
api_runner.issued_credentials,
|
||||
|
||||
Reference in New Issue
Block a user