Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

score-all command #119

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
c405573
make stake pool optional, score-all command
luciotato Jun 26, 2021
fc01071
generate validator-detail.csv
luciotato Jun 27, 2021
697502f
Merge branch 'solana-labs:master' into scorer
luciotato Jun 27, 2021
3e0b405
skip heavy rpc-call, ensure all validators scored
luciotato Jun 27, 2021
c6758e4
Merge
luciotato Jun 27, 2021
f56159c
compute score
luciotato Jun 27, 2021
bd6464f
scripts
luciotato Jun 27, 2021
a700608
parametrize score, do not combine with --confirm
luciotato Jun 30, 2021
1f82f09
fix score-all arguments
luciotato Jul 3, 2021
b562d35
score-all command
luciotato Jul 3, 2021
a4b97a2
add vote-address
luciotato Jul 17, 2021
b9299ca
do not include .vscode
luciotato Jul 17, 2021
a9f3716
Merge master
luciotato Jul 17, 2021
4b78d56
Merge upstream into solana-labs-master
luciotato Jul 17, 2021
d4e4d49
Merge branch 'solana-labs-master'
luciotato Jul 17, 2021
4fdaed2
remove comment block as requested
luciotato Jul 17, 2021
f971ff4
make stake pool optional, score-all command
luciotato Jun 26, 2021
4608fa9
skip heavy rpc-call, ensure all validators scored
luciotato Jun 27, 2021
8a3df58
add vote-address
luciotato Jul 17, 2021
004b7bd
remove comment block as requested
luciotato Jul 17, 2021
528d339
Merge origin
luciotato Jul 17, 2021
c55c904
remove unused var
luciotato Jul 17, 2021
351f31d
act on recommendation - db backward compat
luciotato Jul 24, 2021
e7aa268
add average-position, recompute score every time
luciotato Jul 25, 2021
6eb887e
fix csv headers
luciotato Jul 25, 2021
d6c5dc5
score-all mainnet
luciotato Jul 30, 2021
480b52b
set limit to 33%
luciotato Jul 31, 2021
f3651d4
include 1st outside sec-group
luciotato Jul 31, 2021
8be79ad
apply commission discount to credits more fairly
luciotato Aug 1, 2021
1817d01
better name for table field
luciotato Aug 3, 2021
2a58220
add validator-name, min-avg-position
luciotato Aug 10, 2021
dd30b2b
select top X validators
luciotato Aug 14, 2021
8028451
tilt towards high average
luciotato Aug 18, 2021
c8bdc27
apply data-center concentration penalty
luciotato Aug 21, 2021
72824f3
take TOP 200 validators
luciotato Sep 3, 2021
04738cb
add comments to sql processing
luciotato Sep 12, 2021
92e3c43
new field adj_credits
luciotato Sep 16, 2021
28943a5
add active stake
luciotato Oct 19, 2021
4caeccd
move to avg last 5 epochs
luciotato Nov 2, 2021
bab763f
set score=0 if stake<100
luciotato Nov 7, 2021
81bbd28
extend score cut to top 250
luciotato Nov 21, 2021
879de8d
sql-utils
luciotato Dec 26, 2021
03c8bc9
include last validator in nakamoto coeff
luciotato Dec 31, 2021
6fff2be
Dockerized (#3)
janlegner Jan 19, 2022
d4798c6
Fixed double quotes escaping
janlegner Jan 22, 2022
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/registry-cli
/db
test-ledger/
.vscode
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM alpine:3.14

RUN apk update
RUN apk upgrade
RUN apk add --no-cache bash sqlite rust cargo openssl-dev eudev-dev linux-headers

WORKDIR /usr/local/

ADD program program/
ADD cli cli/
ADD bot bot/
ADD sql sql/
ADD Cargo.lock .
ADD Cargo.toml .
ADD clean-score-all-mainnet.bash .
ADD score-all-mainnet.sh .
ADD import-into-sqlite.sh .

RUN cargo build

CMD ./clean-score-all-mainnet.bash
21 changes: 12 additions & 9 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# stake-o-matic

The release of the binaries is fully automated. Do not create a Github release
manually.
## Build with cargo and run
```bash
cargo build
wget "https://github.com/marinade-finance/staking-status/raw/main/scores.sqlite3" -O "db/score-sqlite3.db"
./clean-score-all-mainnet.bash
```

#### Release Process
1. Create a new tag for the next available release number, see
https://github.com/solana-labs/stake-o-matic/tags, and push it to the repo:
eg, `git tag v42 && git push origin v42`
2. The GitHub workflow automatically triggers a new build, creates a release
with the name of the tag, and uploads the release artifacts. You can monitor
the release process at https://github.com/solana-labs/stake-o-matic/actions
## Build with docker and run
```bash
./docker-build.bash
./docker-run.bash
```
14 changes: 11 additions & 3 deletions bot/src/data_center_info.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::validators_app,
crate::{validators_app, ByIdentityInfo},
log::*,
serde::{Deserialize, Serialize},
solana_sdk::pubkey::Pubkey,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl std::fmt::Display for DataCenterInfo {
#[derive(Debug, Default)]
pub struct DataCenters {
pub info: Vec<DataCenterInfo>,
pub by_identity: HashMap<Pubkey, DataCenterId>,
pub by_identity: HashMap<Pubkey, ByIdentityInfo>,
}

pub fn get(cluster: &str) -> Result<DataCenters, Box<dyn error::Error>> {
Expand Down Expand Up @@ -123,7 +123,15 @@ pub fn get(cluster: &str) -> Result<DataCenters, Box<dyn error::Error>> {
})
.unwrap_or_default();

by_identity.insert(identity, data_center_id.clone());
by_identity.insert(
identity,
ByIdentityInfo {
data_center_id: data_center_id.clone(),
keybase_id: String::from(v.keybase_id.as_deref().unwrap_or("")),
name: String::from(v.name.as_deref().unwrap_or("")),
www_url: String::from(v.www_url.as_deref().unwrap_or("")),
},
);

let mut data_center_info = data_center_map
.entry(data_center_id.clone())
Expand Down
75 changes: 75 additions & 0 deletions bot/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use {
crate::{
data_center_info::{DataCenterId, DataCenterInfo},
generic_stake_pool::ValidatorStakeState,
Config,
},
log::*,
serde::{Deserialize, Serialize},
Expand All @@ -14,6 +15,33 @@ use {
},
};

#[derive(Default, Clone, Deserialize, Serialize)]
pub struct ScoreDiscounts {
pub can_halt_the_network_group: bool,
}

#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct ByIdentityInfo {
pub data_center_id: DataCenterId,
pub keybase_id: String,
pub name: String,
pub www_url: String,
}

#[derive(Default, Clone, Deserialize, Serialize)]
/// computed score (more granular than ValidatorStakeState)
pub struct ScoreData {
/// epoch_credits is the base score
pub epoch_credits: u64,
/// 50 => Average, 0=>worst, 100=twice the average
pub average_position: f64,
pub score_discounts: ScoreDiscounts,
pub commission: u8,
pub active_stake: u64,
pub data_center_concentration: f64,
pub validators_app_info: ByIdentityInfo,
}

#[derive(Default, Clone, Deserialize, Serialize)]
pub struct ValidatorClassification {
pub identity: Pubkey, // Validator identity
Expand All @@ -22,6 +50,9 @@ pub struct ValidatorClassification {
pub stake_state: ValidatorStakeState,
pub stake_state_reason: String,

// added optional validator scoring data
pub score_data: Option<ScoreData>,

// Summary of the action was taken this epoch to advance the validator's stake
pub stake_action: Option<String>,

Expand All @@ -45,6 +76,50 @@ pub struct ValidatorClassification {
pub prioritize_funding_in_next_epoch: Option<bool>,
}

impl ScoreData {
pub fn score(&self, config: &Config) -> u64 {
if self.score_discounts.can_halt_the_network_group
|| self.active_stake < config.score_min_stake
|| self.average_position < config.min_avg_position
// if config.min_avg_position=100 => everybody passes
// if config.min_avg_position=50 => only validators above avg pass
|| self.commission > config.score_max_commission
{
0
} else {
// if data_center_concentration = 25%, lose all score,
// data_center_concentration = 10%, lose 40% (rounded)
let discount_because_data_center_concentration = (self.data_center_concentration
* config.score_concentration_point_discount as f64)
as u64;

// score discounts according to commission
// apply commission % as a discount to credits_observed.
// The rationale es:
// If you're the top performer validator and get 300K credits, but you have 50% commission,
// from our user's point of view, it's the same as a 150K credits validator with 0% commission,
// both represent the same APY for the user.
// So to treat both the same we apply commission to self.epoch_credits
let discount_because_commission = self.commission as u64 * self.epoch_credits / 100;

// give extra score to above average validators in order to increase APY for our users
let points_added_above_average: u64 = if self.average_position > 50.0 {
let above = self.average_position - 50.0;
let multiplier = if above * above > 25.0 { 25.0 } else {above * above};
(multiplier * self.epoch_credits as f64) as u64
} else {
0
};

//result
self.epoch_credits
.saturating_sub(discount_because_commission)
.saturating_sub(discount_because_data_center_concentration)
.saturating_add(points_added_above_average)
}
}
}

impl ValidatorClassification {
pub fn stake_state_streak(&self) -> usize {
let mut streak = 1;
Expand Down
Loading