ifdefelse / ProgPOW

A Programmatic Proof-of-Work for Ethash. Forked from https://github.com/ethereum-mining/ethminer
GNU General Public License v3.0
257 stars 84 forks source link

ProgPoW's handling of Ethash's uneven DAG size is underspecified #31

Open solardiz opened 5 years ago

solardiz commented 5 years ago

Ethash DAG sizes are multiples of 128 bytes, but not of 256. ProgPoW's README.md says:

The DAG is generated exactly as in Ethash.  All the parameters (ephoch length, DAG size, etc) are unchanged.

ProgPoW accesses the DAG in 256-byte chunks, which is a documented change from Ethash. However, it doesn't specify how it's handling the last element of Ethash's original DAG, which is only 128 bytes long. Is that last element perhaps/hopefully never accessed? This needs to be specified fully, and implementations checked for potential unintended behavior.

Also, ProgPoW's bundled implementation of Ethash's DAG initialization has ETHASH_MIX_BYTES changed from 128 to 256. Since the DAG is supposed to be unchanged from Ethash's, this change is probably unneeded (at least for the host-side DAG initialization code that's also unused in the ProgPoW tree?), but it breaks the included (and also unused?) ethash_hash().

The ETHASH_MIX_BYTES macro is reused by the CUDA and OpenCL DAG initialization code, but I guess it's not supposed to make a difference there as well? If so, should it perhaps be reverted to 128 to emphasize that the DAG is indeed unchanged from Ethash's? Or is the change to 256 needed e.g. not to waste resources on computing the last (unused?) 128 bytes? I suggest adjusting the code or comments to address or avoid these questions right in there.

In the plain C implementation of ProgPoW I'm currently playing with, I left Ethash's DAG initialization as-is (with ETHASH_MIX_BYTES at 128) and it's producing the correct (matching your test-vectors.md) digest for block 30k.

AndreaLanfranchi commented 5 years ago

ETHASH_MIX_BYTES is only used in ProgPoW kernel source code generator to compute the number of 256 chunks of the DAG.

It has no effect on DAG generation where ETHASH_MIX_BYTES is not taken into account.

AndreaLanfranchi commented 5 years ago

However, it doesn't specify how it's handling the last element of Ethash's original DAG, which is only 128 bytes long. Is that last element perhaps/hopefully never accessed?

DAG generation creates all nodes as 128. Nodes accessed by ProgPoW are computed like this totalDagSize / ETHASH_MIX_BYTES into an integer. Should original DAG nodes be an odd number (for the given epoch) the last 128 bits of the DAG would not be accessed.