Skip to content

Instantly share code, notes, and snippets.

@IlyaGazman
Last active July 24, 2018 11:59
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save IlyaGazman/6208c1ac82137b409d2a2caec9b83b36 to your computer and use it in GitHub Desktop.
Testing ROW, Race of Work probability to win. See more details here: https://confidence-coin.com/race-of-work-blockchain-without-forks
100 8
10 won 10.09% of the times, he earned 1435.3297619047212
20 won 19.88% of the times, he earned 1406.78452380948
48 won 48.24% of the times, he earned 1335.710714285664
2 won 2.1% of the times, he earned 1061.8154761904239
11 won 11.15% of the times, he earned 1431.9107142856726
5 won 4.68% of the times, he earned 1401.2749999999564
1 won 1.07% of the times, he earned 679.9678571428566
3 won 2.79% of the times, he earned 1247.2059523808973
Total reword 9999.99999999967 / 10000.0
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Random;
import java.util.UUID;
/**
* This is an experimental proof that in
* <a href="https://confidence-coin.com/race-of-work-blockchain-without-forks/">ROW</a>,
* Race of work have, your chances to mine a block are equal to your
* computational power percentage from the entire network, or in other words, the chance to win are equally distributed.
*
* @author Ilya Gazman
*/
public class RowTest {
private MessageDigest sha256;
private RowTest() throws NoSuchAlgorithmException {
sha256 = MessageDigest.getInstance("SHA-256");
}
public static void main(String... args) throws NoSuchAlgorithmException {
new RowTest().start();
}
private void start() {
ArrayList<Integer> list = new ArrayList<>();
Random random = new Random();
list.add(10);
while (sum(list) < 100) {
int value = random.nextInt(100 - sum(list) + 1);
if (value == 0 || list.contains(value)) {
continue;
}
list.add(value);
}
System.out.println(sum(list) + " " + list.size());
byte[][] players = new byte[list.size()][];
int[] score = new int[list.size()];
double[] reword = new double[list.size()];
String guid = UUID.randomUUID().toString();
float totalGames = 1_000;
for (int i = 0; i < totalGames; i++) {
for (int j = 0; j < list.size(); j++) {
int player = list.get(j);
byte[] min = null;
for (int k = 0; k < player; k++) {
byte[] hash = hash(i, guid, k, player);
if (hash.length != 32) {
throw new Error("Hash error");
}
if (min == null || compare(hash, min) == -1) {
min = hash;
}
}
players[j] = min;
}
score[findWinner(players)]++;
rewordPlayers(players, reword);
}
for (int i = 0; i < score.length; i++) {
System.out.println(list.get(i) + " won\t" + score[i] / totalGames * 100 + "%\tof the times, he earned\t" + reword[i]);
}
double totalReword = 0;
for (double v : reword) {
totalReword += v;
}
System.out.println("\nTotal reword " + totalReword + " / " + totalGames);
}
private void rewordPlayers(byte[][] players, double[] reword) {
int rounding = BigDecimal.ROUND_CEILING;
int scale = 32;
BigDecimal total = BigDecimal.ZERO;
for (byte[] player : players) {
BigDecimal playerReword = new BigDecimal(new BigInteger(player));
total = total.add(BigDecimal.ONE.divide(playerReword, scale, rounding));
}
for (int j = 0; j < players.length; j++) {
BigDecimal playerReword = new BigDecimal(new BigInteger(players[j]));
BigDecimal a = BigDecimal.ONE.divide(playerReword, scale, rounding);
BigDecimal b = a.divide(total, scale, rounding);
reword[j] += b.doubleValue();
}
}
private int findWinner(byte[][] players) {
byte[] min = null;
int winner = -1;
for (int i = 0; i < players.length; i++) {
byte[] hash = players[i];
if (min == null || compare(hash, min) == -1) {
min = hash;
winner = i;
}
}
return winner;
}
/**
* if a > b return 1 else if a < b return -1 else return 0
*/
private static int compare(byte[] a, byte[] b) {
int aLength = a.length;
int bLength = b.length;
for (int i = a.length - 1; i >= 0 && a[i] == 0; i--) {
aLength--;
}
for (int i = b.length - 1; i >= 0 && b[i] == 0; i--) {
bLength--;
}
if (aLength > bLength) {
return 1;
} else if (bLength > aLength) {
return -1;
}
for (int k = 0; k < aLength; k++) {
int A = a[k] & 0xff;
int B = b[k] & 0xff;
if (A > B) {
return 1;
}
if (A < B) {
return -1;
}
}
return 0;
}
private byte[] hash(int i, String value, int k, int player) {
value = i + "," + value + "," + k + "," + player;
return sha256.digest(value.getBytes());
}
private int sum(Iterable<Integer> list) {
int total = 0;
for (Integer value : list) {
total += value;
}
return total;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment