Last active
July 24, 2018 11:59
Star
You must be signed in to star a gist
Testing ROW, Race of Work probability to win. See more details here: https://confidence-coin.com/race-of-work-blockchain-without-forks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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