Hey everyone,
I’m curious about how cgminer works. I’ve read some stuff but still confused.
Here’s the scenario I’m looking at: using a GekkoScience Compac F USB miner on mainnet with an average hashrate of 387 GH/s. The nonce range is from 0 to 4.3 billion, right? So, if I’m correct, this miner could theoretically cycle through all nonces in about 1/90th of a second. Shouldn't it be able to hit 90x per second?
Why does cgminer update "nonce2" and "ntime" every 5 seconds?
20 replies 224 views
RogueShardMember
Posts: 22 · Reputation: 220
#2Sep 10, 2018, 01:36 PM
You can tweak the ntime data in the submit_noffset_nonce or resubmit to pull the stratum split every 5 seconds to 2 minutes.
There’s a bit more info on it here.
Hey Snowy Pear,
Thanks for making a new account just to reply. I checked out submit_noffset_nonce, but I can’t seem to change the ntime every 5 seconds or even turn it off for testing. I tried disabling functions like modify_ntime and others, but it still increments every 5 seconds after a debug restart. What am I missing here?
token_sageFull Member
Posts: 66 · Reputation: 625
#4Sep 10, 2018, 07:14 PM
NTime is just a Unix timestamp.
If you take those hex values like 63667f00 or 63667f05 and convert them, you can check the dates. I think cgminer just updates the block template with a new timestamp every 5 seconds to keep things efficient since Bitcoin timestamps don’t need to be super precise.
Yeah, I get it’s a Unix time format. But I want to know where in the code this 5-second interval comes from. I’ve been digging through cgminer.c but can’t seem to find it.
By the way, I noticed in the debug log that not only ntime resets every 5 seconds, but nonce2 does too. What’s with that 5-second thing?
token_sageFull Member
Posts: 66 · Reputation: 625
#6Sep 10, 2018, 11:34 PM
Glad you figured it out!
It’s tied to the block update process, specifically at line 9364.
Makes sense that nonce resets with a new block template, right? Glad you found the code. But I’m curious about your intent. Are you trying to change the reset timer or something? Why?
Just for educational purposes.
Trying to get a grip on how the code works.
In cgminer, whenever there’s a new block or update, it creates a new "ntime" when it gets the block info. Roughly every 60 seconds, the pool sends updated block info. Check out the parse_notify() function.
Nonce2 is used to create more local block header data for hashing and generating a new merkleroot. It changes quickly, see gen_stratum_work.
token_sageFull Member
Posts: 66 · Reputation: 625
#10Sep 11, 2018, 08:44 AM
Yes, I’m working on gen_solo_work since I’m mining solo on my own bitcoind node. I understand why nonce and nonce2 are used. It’s explained well in other threads.
But I’m asking about nonce2, not the original nonce. If nonce2 increments, what’s its upper limit? When I decrease nonce2 in cgminer, it starts at 18446744073709551615. Is that the max?
Oh man, my bad. I got confused with all the numbers!
I was asking if you modified the code to prevent the nonces from resetting after 5 seconds. Because in your quote, the timestamp didn’t change for a whole 5 minutes, right? So you did change the code.
token_sageFull Member
Posts: 66 · Reputation: 625
#12Sep 12, 2018, 10:45 PM
I’m just trying to see what happens in mining live. Yeah, I did freeze ntime for testing, but not nonce2. I upped the timer from the default to 15 seconds just to check if it worked. Still not where I want to be.
What I want is to see all nonces sent to hardware, how cgminer threads and queues them, and the actual shares generated.
You should add some debug prints!
Pipe stdout to a file or write to a file directly, but that’s a bit trickier.
token_sageFull Member
Posts: 66 · Reputation: 625
#14Sep 13, 2018, 04:09 AM
I’ve done that, but I’m struggling to get the nonce displayed. I changed the status bar to show the current nonce, but I just see "0". I tried %u too and got similar results. I’m not a dev, just trying to read the code. I don’t think the format is the issue; it seems like the nonce isn’t defined or used in that code section.
Honestly, I haven’t dug that deep into cgminer. If nonce is always 0, maybe it’s just cycling through nonce2 instead? Not sure. Maybe we can tag @kano; he knows a lot.
After reading your messages, I see some gaps.
1. Nonce2 is only for creating the next local block header. It resets to 0 when a new block header comes in. It’s a 64-bit integer, affecting only the merkleroot. Lots of local block header data is created for ASICs to find valid hashes.
2. cgminer doesn’t cycle nonce from 0 to 4.
Nice explanation, thanks!
What if nonce2 is an unsigned 32-bit integer and the ASIC miner is super powerful? What happens if nonce2 runs out before a new block header arrives? Does cgminer not have control over the nonce being tested?
You don’t want cgminer, which runs on a slow CPU, to manage nonce increments; that’s too fast for it. Chips like Bitmain’s have address pins for a reason, allowing multiple chips to handle different nonce ranges without overlap.
Cgminer doesn’t send a full block header to the ASIC. It sends a midstate, which is a partially computed hash of the block.
token_laserMember
Posts: 145 · Reputation: 208
#19Sep 14, 2018, 06:17 PM
Thanks for that detailed explanation!
Does this mean nonce2 moves slower because it’s managed by the CPU? Couldn’t we send nonce2 to the ASIC chip like nonce so it processes faster? For example, set nonce to 123, generate midstate work for nonce2, and let the ASIC handle nonce2 cycles?
Seems like there’s a lot of confusion about the code.
According to the code, mining with an ASIC involves receiving work from the pool every 30 seconds. That’s the optimal time.
During those 30 seconds, the same pool work is reused by modifying nonce2 to create a unique merkleroot.