Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Block difficulty is always '0' (zero) #662

Closed
vicnaum opened this issue Nov 11, 2020 · 7 comments
Closed

Block difficulty is always '0' (zero) #662

vicnaum opened this issue Nov 11, 2020 · 7 comments

Comments

@vicnaum
Copy link

vicnaum commented Nov 11, 2020

image

Expected Behavior

Hardhat (on the left) has difficulty and totalDifficulty values set

Current Behavior

Ganache (on the right) has both difficulty and totalDifficulty values equal to zero.

Possible Solution

Both projects use ethereumjs-vm version v4.2.0.

I assume the difference happens during block creation (as far as I remember Hardhat set difficulty based on the latest block):

https://github.com/nomiclabs/hardhat/blob/6c3cdb7445c3b2960ed6bfce50d09bc11338479e/packages/hardhat-core/src/internal/hardhat-network/provider/node.ts#L1040

Ganache doesn't seem to have any difficulty-related header assignment:

https://github.com/trufflesuite/ganache-core/blob/1177fe8a2711066a1b082b15d22585158001e80d/lib/blockchain_double.js#L600

P.S. Btw, also ethereumjs/ethereumjs-monorepo#929 was merged 5 days ago - introducing a new way of setting a difficulty in ethereumjs-vm (but Hardhat was setting difficulty before this release).

@davidmurdoch
Copy link
Member

Thanks for opening this issue. Are you using forking?

@vicnaum
Copy link
Author

vicnaum commented Nov 12, 2020

Tried with and without forking - neither makes a difference - difficulty is still at 0.

@davidmurdoch
Copy link
Member

Without forking difficulty and totalDifficulty should always be 0, and the nonce and mixHash values will also always be 0 (since ganache does not do any PoW). When getting a block before the fork number (or latest at the time of forking) difficulty and totalDifficulty should match the original block's values.

Setting difficulty to 0 in ganache is intentional, as we currently take the stance that because difficulty is a value that is used to ensure new blocks aren't generated too quickly or too slowly, and ganache's default is a 0-second block time, so a difficulty of 0 is the target.

When setting ganache to have a non-zero blocktime, you could make the argument that we should calculate difficulty and mixhash... but what values do we put?

I'm definitely open to a other ideas, so please feel free to give arguments for why we should change.

@vicnaum
Copy link
Author

vicnaum commented Nov 12, 2020

When forking - it doesn't retain the original forked values - just resets both difficulty and totalDifficulty to 0.

image

The general logic about it being 0 as the blocks are instantaneous is quite solid. Although some projects (like Hardhat) use difficulty 1 for that (so the totalDifficulty keeps increasing). I don't know which logic is better.

The reason why we need this on a synthetic developer chain - we're currently developing some intricate contracts that rely on blocks difficulties to make decisions (they values are passed with block header RLP's, decoded, and verified, as EVM cannot access them directly).

But there's no way to fully test these contracts currently, except maybe on real networks with real mining - and that's also not quite good for testing - as we cannot really affect difficulty to test different values. So currently we're designing some hacks and mocks, but it would be nicer if contract really tested the values from the chain.

So I was thinking about several solutions to this:

  1. Setting a fixed value during network creation
  2. Setting a randomized value during network creation (a range?)
  3. Introducing some RDP calls (a-la evm_increaseTime) - maybe evm_increaseDifficulty or evm_setDifficulty or something like that (it could work with both instant and non-zero blocktime).

Or can be a mix of the above.

@davidmurdoch
Copy link
Member

Ah, thanks for the use-case example.

Also, looks like there are two bugs in forking:

  1. On blocks fetched from the original chain we are setting difficulty to totalDifficulty.
  2. Even though we've intended for difficulty to be 0, we don't keep the totalDifficulty around, as we should.

As for your use-case example, i'll talk to the team internally and see what we can come up with!

@davidmurdoch davidmurdoch added this to the 3.0.0 milestone Jan 12, 2021
@eggplantzzz
Copy link
Contributor

#771 addresses this issue.

@eggplantzzz
Copy link
Contributor

merged!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants