Informal Discussion -- "How does the minting process work?"

Thanx for sharing… It clarifies things a bit :wink:

Thanks for sharing that Ben, that’s good information!

And thank you Sigmike for helping Ben help us all :slight_smile:

When I ran a test with this with BCX / Battlecoin

and for each one it checks whether it matches the target difficulty

…that part was untrue. But BCX’s code appeared to be based on ppcoin 0.2.0 with a stake bug in it. Not sure. Either way, it keep trying to mint the oldest transaction. It didn’t try the 3 oldest transactions even though they were all transactions that were able to be used as stake.

My oldest transaction was something small like 2 BCX and my next one was huge, like 1500 BCX, yet it would never try to mint the 1500 BCX until the 2 BCX transaction stake was used.

I found this to be a problem, and when I saw that BCX didn’t have devs to properly fix the coin at that time for other issues, I dumped mine and gave up.

I don’t know if any of this is inherent in ppcoin still, but it is my experience with battlecoin’s minter.

Is the search space [0, 2^256) or [0, 2^32) ?

I’m wondering whether we can understand it as following: PoS minting is just like a PoW merge mining nonce search for different chains/output txs. So each second a nonce is picked in the search space, and this nonce is used to get something similar to the hash for each output transaction in your wallet ( say, 600 PPC * 31days, 6000PPC * 60 days, …), and then compare those hashes with current “target”/“difficulty” to decide whether it hits and generates a PoS block.

That’s my logic understanding. More details should be studied from the source code.

[quote=“ppcman, post:4, topic:2189”]When I ran a test with this with BCX / Battlecoin

and for each one it checks whether it matches the target difficulty

…that part was untrue.[/quote]

Peercoin does select all your balance (minus reserve): https://github.com/ppcoin/ppcoin/blob/master/src/wallet.cpp#L1240
And tries each output: https://github.com/ppcoin/ppcoin/blob/master/src/wallet.cpp#L1246
And only aborts if it finds a matching kernel.

Each second you get a new 256 bits hash so the maximum value is 2^256-1.

There’s no nonce. Or you can say the nonce is the timestamp which changes every second. This timestamp is added to other data from your transaction and you produce a 256 bits hash with that. And you compare this big number with (current target * coin age). If your hash is below this adjusted target, your kernel is valid to make a PoS block.

It is great to see Sigmike explaining this. I’ve been trying to understand this from an analytical and logical point of view for months. Having a coder explaining makes it all a bit more concrete. Thanks Sigmike and thanks Ben for asking the ‘smart’ questions.

I’m glad to hear that the lottery analogy in the “Long PoS thread” still stands (more coins/ tickets, more chances to mint / win the lottery). Each block we have a new draw 8)

Since the network has a tolerance of two hours of time stamp error, does it mean one can try 14400 different time stamps per second?

Since the network has a tolerance of two hours of time stamp error, does it mean one can try 14400 different time stamps per second?[/quote]

Yes. There are other limits involved but you can try more timestamps per second. The client already tries some previous timestamps if you missed them.

But if you try the next 14400 timestamps at time t, then at time t+1 you’ll try 14399 timestamps you’ve already tried, and only try 1 new. So you still try only 1 new timestamp per second.

If you do that it may still be a little easier to find a block if the difficulty changes a lot (because you’ll try more timestamps when the difficulty is low). But it’s probably not significant. And you wouldn’t get more reward, you’d only a part of it earlier.

Since the network has a tolerance of two hours of time stamp error, does it mean one can try 14400 different time stamps per second?[/quote]

Yes. There are other limits involved but you can try more timestamps per second. The client already tries some previous timestamps if you missed them.

But if you try the next 14400 timestamps at time t, then at time t+1 you’ll try 14399 timestamps you’ve already tried, and only try 1 new. So you still try only 1 new timestamp per second.[/quote]

Is it right? In the (N+1)th second the difficulty and the hash for the previous block have all changed so you won’t get the same hash with timesptamp=N as you did in the Nth second (when timesptamp was N). All 14400 hashes would be new compared with the last second.

And you wouldn't get more reward, you'd only a part of it earlier.
That is true. But the minters with small stakes have incentive to get a block earlier or they don't get any POS for a long time (years). Or for those who want to spend the coins that have generated coin-ages but haven't gotten POS.

Difficulty and hash of previous block only change when there is a new block, which happens about every 10 minutes, not every second.

Difficulty and hash of previous block only change when there is a new block, which happens about every 10 minutes, not every second.[/quote]

You are right. So when there is a new block this can work once. On average there is a 14400/60/10=24 times advantage. (14400 is the number of seconds in +/-2hr). Every stake that finds a POS block will be off for 30 days. So actually it will take 30246=4320 stakes to be able to have one exploit for every block. Nodes doing this will push up POS difficulty, reducing other stakes’ access to POS blocks by 24 times, hence weakening network security. Unless I get it wrong somewhere it seems a serious problem.

That calculation was not totally correct. It assumed anyone who does this will finish looking for a block within a second, and will repeat the same the next second. Actually he has a 14400 times advantage as long as a valid stake (unspent input). If it takes 10 minutes to try all of them, he will have a solid 14400 times advantage.

Is it right? In the (N+1)th second the difficulty and the hash for the previous block have all changed so you won’t get the same hash with timesptamp=N as you did in the Nth second (when timesptamp was N). All 14400 hashes would be new compared with the last second.[/quote]

Actually the previous block hash in not part of the hash you compute in PoS. So the 14400 hashes stay the same even if there’s a new block.
The only thing that may change is the difficulty.

[quote=“sigmike, post:15, topic:2189”]Actually the previous block hash in not part of the hash you compute in PoS. So the 14400 hashes stay the same even if there’s a new block.
The only thing that may change is the difficulty.[/quote]

Since the new kernel is found by hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDayWeight can’t you try 7200+600 nTimes for every prev block? Other people can only try 600 times before the next block is found, in average 600 sec. The 7200 is the number of seconds in the 2hr clock error that the network allows you to have. Maybe it is 14400. I am not sure. But anyway in this exploit basically you pretend to have a wrong system clock.

btw I don’t really understand stakeModifier.

You can try, but since the prev block is not used in the hash, you’ll find the same hash for every prev block. So you don’t get any more chances when the prev block changes.

Note that txPrev.block is the block where your coins were confirmed, not the last block in the blockchain.

It is generated a few blocks after your coins are confirmed. It exists to prevent you from precalculating when you’ll be able to find a block before the transaction is confirmed. It doesn’t change over time either.

Aha that is what I didn’t get. Thanks. So the exploit only get an extra two hours. That is no big deal.

But if nothing in the expression changes except nTime, bnTarget, and nCoinDayWeight which is a known function of nTime , this means that I can calculate when in the future I likely will be getting a kernel. ???

Yes, if you can guess the difficulty.

Yes, if you can guess the difficulty.[/quote]

The difficulty fluctuates around a relatively slow changing average hence can be estimated at some certainly. For a particular stake, anyone who wants take advantage of knowing roughly when the stake will find a kernel might skip minting before time is about up. This stake still contributes to supporting the network. This in itself is harmless. However if a person has many stakes of similar coin age, he could use this knowledge to spend those stakes that will find stakes far in the future, hence improve the average block finding rate for all his stakes; Or he could immediately send the stake that needs more than average time to find a kernel to himself again, if the odd to get a better time, and the compound interest outweighs the tx fee.
I am glad that in any case the impact to network security is limited.

Yes, if you can guess the difficulty.[/quote]

That’s exactly what does the little findstake tool by kac-: https://github.com/kac-/umint/blob/master/tools/findstake/find.go

thehuntergames implemented a nice html/javascript version of it: https://github.com/jointhepartypooper/FindstakeJS