Hi EK, question about ElasticPL. I understand that the verify command identifies what work meets the bounty critieria, but what qualifies that the other pow work actually took place. For example, in your good.epl, obviously only hashes beginning with 32 bits of zero meet the bounty, but what shows that the pow submissions were actual hashes for that block header and that one miner has higher hashrate than another? Or in the elastic world are all miners equal regardless of how much work they do?
I'd like to look into epl and the miner a bit more, so I'm trying to better understand how this works.
The best way to explain would be to first take a look at the relevant code:
public static byte[] byteHash(int randomInput[], int output[]) throws NoSuchAlgorithmException {
MessageDigest m = getMessageDigest("SHA-256");
m.reset();
ByteBuffer byteBuffer = ByteBuffer.allocate(output.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(output);
ByteBuffer byteBufferIn = ByteBuffer.allocate(randomInput.length * 4);
IntBuffer intInBuffer = byteBufferIn.asIntBuffer();
intInBuffer.put(randomInput);
byte[] array = byteBuffer.array();
byte[] array2 = byteBufferIn.array();
m.update(array);
m.update(array2);
byte[] digest = m.digest();
return digest;
}
public boolean verifyPOW(BigInteger target) {
int in[] = getRandomIntArray();
int out[] = getOutState();
try {
byte[] bsh = byteHash(in, out);
BigInteger val = byteHashToLong(bsh);
if (val.compareTo(target)==-1)
return true;
} catch (NoSuchAlgorithmException e) {
}
return false;
}
Think of the verifyPOW function to be inside the "code execution engine" that runs the Elastic PL code.
It takes one argument, the target value that will later be relevant and that changes with every block depending on the recent POW submission rate.
Then it takes the input array (the one that was given by the miner, often 3-12 random integers) and the out state. The out state is the entire content of the virtual machine memory ... in this case the entire array m[0] until m[256]
*after the execution of the program* (
lets for now assume we allow only 256 integers in memory, this value is bigger now actually and to recall, the m[.] slots are the only place in the VM where users can store something).
Then a hash is calculated based on the input integers and the final memory state integers. It's basically a SHA256 fed with the binary representation of a) the output state integers and then b) the input integers (
the order is relevant to avoid precomputation by using the first part of the hash (the input integers) as a sort of midstate).
Then the resulting hash is checked if it meets the desired target value. That means, if the value of the hash interpreted as a BigInteger is smaller than the target value. If it is, then a POW is found.
If too many POW are found, the target value becomes smaller and it gets harder to find hashes that match the requirements.
If you have any suggestions, critics or opinions regarding to this scheme, that would be greatly appreciated!!!!