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 perioid_seed issue #14

Closed hackmod closed 5 years ago

hackmod commented 5 years ago

this is a bug report.

since ProgPoW utilize block_number to get the prog_seed = block_number / PROGPOW_PERIOD(50), we need to obtain block_number from the geth/pool node.

now, eth_getWork() support block_number info. from the latest geth 1.8.18, so I've made small fix to use block_number to cuda_init() correctly,

@@ -319,6 +323,7 @@ bool CUDAMiner::s_noeval = false;

 bool CUDAMiner::cuda_init(
        size_t numDevices,
+       uint64_t block_number,
        ethash_light_t _light,
        uint8_t const* _lightData,
        uint64_t _lightBytes,
@@ -346,7 +351,8 @@ bool CUDAMiner::cuda_init(
                m_search_buf = new volatile search_results *[s_numStreams];
                m_streams = new cudaStream_t[s_numStreams];

-               uint64_t dagBytes = ethash_get_datasize(_light->block_number);
+               cnote << "block_number " << _light->block_number; // wrong value
+               uint64_t dagBytes = ethash_get_datasize(block_number);
                uint32_t dagElms   = (unsigned)(dagBytes / ETHASH_MIX_BYTES);
                uint32_t lightWords = (unsigned)(_lightBytes / sizeof(node));

@@ -376,7 +382,8 @@ bool CUDAMiner::cuda_init(
                hash64_t * dag = m_dag;
                hash64_t * light = m_light[m_device_num];

-               compileKernel(_light->block_number, dagElms); // wrong block_number
+               uint64_t prog_seed = block_number / PROGPOW_PERIOD;
+               compileKernel(prog_seed, dagElms);

                if(!light){
                        cudalog << "Allocating light with size: " << _lightBytes;

but the result is following, image


testnet genesis with progpowBlock: 0

test with https://github.com/ethereum/go-ethereum/pull/17731 + eth_getWork() fix https://github.com/ethereum/go-ethereum/pull/18038

{
  "config": {
    "chainId": 1357,
    "homesteadBlock":0,
    "eip155Block":0,
    "eip158Block":0,
    "progpowBlock":0,
    "ethash": { }
  },
  "difficulty": "0x2000",
  "timestamp": "0x5be6530c",
  "nonce": "0x0000000000000042",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x",
  "gasLimit": "3141592",
  "alloc": { }
}

image

image

image


mininig command : $ /share/ProgPOW/build/ethminer/ethminer -U --cuda-devices 0 -P http://127.0.0.1:8485

some hunks of quick and dirty patch.

diff --git a/libethcore/EthashAux.h b/libethcore/EthashAux.h
index e74c345..1ea9b9e 100644
--- a/libethcore/EthashAux.h
+++ b/libethcore/EthashAux.h
@@ -72,7 +72,8 @@ struct WorkPackage
     explicit WorkPackage(BlockHeader const& _bh)
       : boundary(_bh.boundary()),
         header(_bh.hashWithout()),
-        epoch(static_cast<int>(_bh.number()) / ETHASH_EPOCH_LENGTH)
+        epoch(static_cast<int>(_bh.number()) / ETHASH_EPOCH_LENGTH),
+        height(static_cast<uint64_t>(_bh.number()))
     {}
     explicit operator bool() const { return header != h256(); }

@@ -82,6 +83,7 @@ struct WorkPackage
     int epoch = -1;

     uint64_t startNonce = 0;
+    uint64_t height = 0;
     int exSizeBits = -1;
     int job_len = 8;
 };
diff --git a/libpoolprotocols/getwork/EthGetworkClient.cpp b/libpoolprotocols/getwork/EthGetworkClient.cpp
index 58968d4..a84c576 100644
--- a/libpoolprotocols/getwork/EthGetworkClient.cpp
+++ b/libpoolprotocols/getwork/EthGetworkClient.cpp
@@ -98,6 +98,7 @@ void EthGetworkClient::workLoop()
                                WorkPackage newWorkPackage;
                                newWorkPackage.header = h256(v[0].asString());
                                newWorkPackage.epoch = EthashAux::toEpoch(h256(v[1].asString()));
+                               newWorkPackage.height = strtoul(v[3].asString().c_str(), nullptr, 0);

                                // Since we do not have a real connected state with getwork, we just fake it.
                                // If getting work succeeds we know that the connection works
@@ -111,6 +112,7 @@ void EthGetworkClient::workLoop()
                                if (newWorkPackage.header != m_prevWorkPackage.header) {
                                        m_prevWorkPackage.header = newWorkPackage.header;
                                        m_prevWorkPackage.epoch = newWorkPackage.epoch;
+                                       m_prevWorkPackage.height = newWorkPackage.height;
                                        m_prevWorkPackage.boundary = h256(fromHex(v[2].asString()), h256::AlignRight);

                                        if (m_onWorkReceived) {
diff --git a/libprogpow/ProgPow.cpp b/libprogpow/ProgPow.cpp
index b55b14e..4a4a4b4 100644
--- a/libprogpow/ProgPow.cpp
+++ b/libprogpow/ProgPow.cpp
@@ -14,12 +14,10 @@ void swap(int &a, int &b)
     b = t;
 }

-std::string ProgPow::getKern(uint64_t block_number, kernel_t kern)
+std::string ProgPow::getKern(uint64_t prog_seed, kernel_t kern)
 {
     std::stringstream ret;

-    uint64_t prog_seed = block_number / PROGPOW_PERIOD;
-
     uint32_t seed0 = (uint32_t)prog_seed;
     uint32_t seed1 = prog_seed >> 32;
     uint32_t fnv_hash = 0x811c9dc5;
ifdefelse commented 5 years ago

Thanks for the bug report. The miner has only been used for algorithm development up until this point. The fact that "block_number" was actually the epoch number is a known limitation that we were waiting for other infrastructure changes in order to fix, which now seem to be in place.

It looks like it's crashing when compiling the kernel after initializing to a new DAG epoch, which for some reason resets the CUDA context. There's some CUDA sequencing that needs to be figured out around that.

ifdefelse commented 5 years ago

Thanks for the changes. Pull request merged so closing this out.