Skip to content

Commit

Permalink
Feature: Add whitelist voter support for private pools
Browse files Browse the repository at this point in the history
This allows pools to choose their voters, and only pay them.
  • Loading branch information
chris.orogvany committed Mar 13, 2018
1 parent 0f7b8dd commit 2db7af6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
37 changes: 15 additions & 22 deletions config/semuxpool.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# #######################################
# General/required configuration
#
# #######################################

# Delegate Address
delegateAddress = <FILL IN DELEGATE ADDRESS>
Expand All @@ -26,10 +26,14 @@ debugMode = true
# What % of fees to pay for hosting/delegate registration (0.1 = 10% fee)
# As a pool needs to burn 1000 SEM for delegate, these pool fees are higher than most
# pools to start. After a delegate has earned back its initial burn, lower fees make sense.

poolFeePercent = 0.20

#
# You can also set up your pool to only pay
# specified users. this is useful when running a private pool
# based on trusted members, and pay them based on their votes
# format is 0xVoterOnesAddress, 0xVoter2sAddress, ...
voterWhiteList =

# Connection for REST API
apiHost = localhost
apiUser = user
Expand All @@ -42,29 +46,18 @@ apiPort = 5171
# Comment out to go back to per block # payouts
payoutTime = 13:00

# Minimum Payout (in SEM)
minPayoutSem = 0.25

# #######################################
# General/Advanced Pool configuration
# (leaving these as defaults is fine)
# #######################################

# To prevent whales from moving votes in after ensuring their validator
# To prevent whales from moving votes in after ensuring their validator state is guarenteed
# We need to have a minimum age on votes before counting them.
minimumVoteAgeBeforeCounting = 200

# Experimental!
# TODO - work in progress - this currently does nothing, just starting a feature request from Phash
# To encourage longterm voters, a pool's fees are high at first, but drop over time
# as a vote ages like fine wine.
# So a user votes 100 on day 1. Then on day 10, they vote another 100
# The fees for the first 100 are low, and the fees on the later one are higher, since they are
# new. Unvotes come out of the oldest bucket, to penalize pool jumping, and encourage
# long term voting.
feeReduction.enabled = false
feeReduction.highestFee = 0.20
feeReduction.lowestFee = 0.02
# number of days before lowest fee is reached
feeReduction.daysToAge = 30

# Experimental!
# Large voters unvoting can be a big pain for validators, as they can leave the pool
# without warning and leave the pool without validator state, as validators are well balanced
Expand All @@ -78,6 +71,7 @@ feeReduction.daysToAge = 30
# enable it!
# Note: user's can effectively bypass this feature if they unvote all but 1 sem.
dontPayPoolQuitters = false

# address to collect void payments. If you need to distribute these votes in the future
# the funds are kept safe. They can also be distributed to active voters if you wish, after some grace
# period has occurred.
Expand All @@ -96,9 +90,6 @@ loggingIntervalMs = 3600000
# data directory for payouts
dataDirectory = payouts

# Minimum Payout (in SEM)
minPayoutSem = 0.25

# the note to apply on payments
paymentNote = semuxpool.com

Expand All @@ -119,6 +110,8 @@ payoutEveryNBlocks = 2880
# If you change percent below default, you will not be able
# to list your delegate on semuxpool.com
# But you can still advertise yourself.
# Even setting this to 0.005 would be appreciated and doesn't affect your bottom line.
# Setting this to 0 is unfortunate.
developerBeerFundPercent = 0.02

# Whether to list this on semuxpool.com
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/com/semuxpool/pool/PoolRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ public static void main(String[] args) throws IOException, SemuxException

PoolProfitAddresses poolProfitsAddress = PoolProfitAddresses.fromString(properties.getProperty("poolProfitsAddress"));

Set<String> voterWhitelist = new HashSet<>();
String[] voterWhitelistString = properties.getProperty("voterWhiteList", "").split(",");
for (String whitelist : voterWhitelistString)
{
if (!whitelist.trim().isEmpty())
{
voterWhitelist.add(whitelist.trim());
}
}

poolAddresses.addAll(poolProfitsAddress.getAddresses());
boolean submitToAggregationSite = Boolean.valueOf(properties.getProperty("submitToAggregationSite", "false"));
long startBlock = Long.valueOf(properties.getProperty("startProcessingAtBlock", "0"));
Expand Down Expand Up @@ -98,7 +108,9 @@ public static void main(String[] args) throws IOException, SemuxException
//
//persistence
Persistence persistence = new JsonPersistence(payoutsDirectory);
BlockResultFactory blockResultFactory = new BlockResultFactory(client, poolPayoutPercent, developerBeerFundPercent, blockReward, poolProfitsAddress, minimumVoteAgeBeforeCounting);
BlockResultFactory blockResultFactory = new BlockResultFactory(
client, poolPayoutPercent, developerBeerFundPercent,
blockReward, poolProfitsAddress, minimumVoteAgeBeforeCounting, voterWhitelist);

//
//payer
Expand Down
17 changes: 16 additions & 1 deletion src/main/java/com/semuxpool/pool/block/BlockResultFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Take a block and convert to a BlockResult
Expand All @@ -30,15 +32,17 @@ public class BlockResultFactory
private final PoolProfitAddresses poolProfitsAddress;
private Integer minimumVoteAgeBeforeCounting;
private final Long blockReward;
private Set<String> voterWhitelist = new HashSet<>();

public BlockResultFactory(SemuxClient client, float poolPayoutPercent, float donationPercent, Long blockReward, PoolProfitAddresses poolProfitsAddress, Integer minimumVoteAgeBeforeCounting)
public BlockResultFactory(SemuxClient client, float poolPayoutPercent, float donationPercent, Long blockReward, PoolProfitAddresses poolProfitsAddress, Integer minimumVoteAgeBeforeCounting, Set<String> voterWhitelist)
{
this.client = client;
this.poolPayoutPercent = poolPayoutPercent;
this.blockReward = blockReward;
this.donationPercent = donationPercent;
this.poolProfitsAddress = poolProfitsAddress;
this.minimumVoteAgeBeforeCounting = minimumVoteAgeBeforeCounting;
this.voterWhitelist = voterWhitelist;
}

public BlockResult getBlockResult(Block block) throws IOException, SemuxException
Expand Down Expand Up @@ -151,6 +155,17 @@ private Map<String, Long> getAgedVotesForBlock(Block block) throws IOException,
//only count votes that are older than threshold
// new version will have block on transaction, til then, we keep track of dates

//if we have a voter whitelist, votes only count if they're in whitelist
if (!voterWhitelist.isEmpty() && !voterWhitelist.contains(transaction.getFrom()))
{
if (transaction.getType().equals("VOTE"))
{
logger.warn("Not counting votes from " + transaction.getFrom() + " - " + transaction.getType());
}

continue;
}

if (transaction.getType().equals("VOTE"))
{
//votes only count when aged.
Expand Down

0 comments on commit 2db7af6

Please sign in to comment.