-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create blockhash_refactoring.md #210
Conversation
Stores blockhashes in the state, reducing the protocol complexity and the need for client implementation complexity in order to process the BLOCKHASH opcode. Also extends the range of how far back blockhash checking can go, with the side effect of creating direct links between blocks with very distant block numbers, facilitating much more efficient initial light client syncing.
whats |
Perhaps SYSTEM would be a better term. It's an account that represents messages sent "by the protocol", that system contracts might assign special privileges to. |
I suggest SYSTEM as well, because SUPERUSER sounds like there's an actual user responsible. |
Please renumber as eip-210 and we will merge this as a draft. |
EIPS/blockhash_refactoring.md
Outdated
else: | ||
if ~calldataload(0) >= block.number or ~calldataload(0) < {METROPOLIS_FORK_BLKNUM}: | ||
return 0 | ||
if block.number - ~calldataload(0) >= 256: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be if block.number - ~calldataload(0) < 256
probably?
Since BLOCKHASH contract code is added to the state its exact bytecode must be specified. |
EIPS/blockhash_refactoring.md
Outdated
BLOCKHASH_CONTRACT_CODE is set to: | ||
|
||
``` | ||
0x73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me this is no-go, because we can't audit the code here. Can we have it in assembly code? If you can't do it ask someone from solidity team to do it. They have nice assembly language that maps 1 to 1 to EVM bytecode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is a sample (probably broken) implementation, though not sure it is easier to read: https://gist.github.com/axic/c97d104ac63a97049a5d2559ba43460f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need the bytecode. EXTCODECOPY
would copy from the bytecode. It's also good if some code is attached in some other languages, with a link to a specific version of a compiler/assembler.
EIPS/blockhash_refactoring.md
Outdated
* `VALUE`: 0 | ||
* `DATA`: 32 byte zero-byte-leftpadded integer representing the stack argument with which the opcode was called | ||
|
||
Also, the gas cost is increased from 20 to 800 to reflect the higher costs of processing the algorithm in the contract code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The serpent code below seems to take more than 800 gas for reading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense setting the cost to the upper bound of what the read actually costs.
If the current proposed rules make that upper bound very large and therefore pose an unrealistically high cost for the opcode, then I would suggest:
- have a contract which stores less and has a lower higher bound or
- limiting the parameter to 256 (as currently) for the opcode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the gas cost increase from METROPOLIS_FORK_BLKNUM
or METROPOLIS_FORK_BLKNUM + 256
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the increase at METROPOLIS_FORK_BLKNUM
, as all previous cost changes happened at the fork block
Is there any reasoning for the rules of storing the block hashes? Would a more simple rolling buffer of a fixed item count be more safe as a first milestone and introducing a more sophisticated contract later? |
EIPS/blockhash_refactoring.md
Outdated
|
||
* `METROPOLIS_FORK_BLKNUM`: TBD | ||
* `SUPER_USER`: 2**160 - 2 | ||
* `BLOCKHASH_CONTRACT_ADDR`: 0xf0 (ie. 240) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be a continuous address or is there a special reason for using 0xf0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked about this before. The answer was this is not regular precompiled contract, because you deploy real bytecode. I think it make sense, because from EVM you don't need additional check "if precompiled" to use this contract.
However, I'd use address of 0x100 to leave the lower byte for precompiled contracts only.
Because of the incoming RETURNDATA changes #211, we have to decide what the contract returns in case of invalid block number or some other exceptional condition (e.g. value transfer). Options are:
|
I can start writing tests for the contract if you are happy with using pyethereum for it. |
EIPS/blockhash_refactoring.md
Outdated
If `block.number >= METROPOLIS_FORK_BLKNUM`, then when processing a block, before processing any transactions execute a call with the parameters: | ||
|
||
* `SENDER`: SUPER_USER | ||
* `GAS`: 1000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the gas price and the nonce of this call transaction?
EIPS/blockhash_refactoring.md
Outdated
* `GAS`: 1000000 | ||
* `TO`: BLOCKHASH_CONTRACT_ADDR | ||
* `VALUE`: 0 | ||
* `DATA`: 32 byte zero-byte-leftpadded integer representing the stack argument with which the opcode was called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the gas price and the nonce of this call? I guess this is just a message call and not a separate transaction.
EIPS/blockhash_refactoring.md
Outdated
If `block.number >= METROPOLIS_FORK_BLKNUM + 256`, then the BLOCKHASH opcode instead returns the result of executing a call with the parameters: | ||
|
||
* `SENDER`: <account from which the opcode was called> | ||
* `GAS`: 1000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when 1000000
is more than "all-but-64th" of the remaining gas? A usual CALL
instruction would lower the number automatically.
EIPS/blockhash_refactoring.md
Outdated
* `VALUE`: 0 | ||
* `DATA`: <32 bytes corresponding to the block's prevhash> | ||
|
||
If `block.number >= METROPOLIS_FORK_BLKNUM + 256`, then the BLOCKHASH opcode instead returns the result of executing a call with the parameters: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the call-stack depth limit of 1024 still relevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This question was answered in #210 (comment)
EIPS/blockhash_refactoring.md
Outdated
|
||
If `block.number >= METROPOLIS_FORK_BLKNUM + 256`, then the BLOCKHASH opcode instead returns the result of executing a call with the parameters: | ||
|
||
* `SENDER`: <account from which the opcode was called> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Github Markdown renderer doesn't show this text in angle brackets for some reason
In the last call a decision was made that the BLOCKHASH opcode (the opcode, not directly calling the contract!) only works for the last 256 blocks as before. Hence, there are now three equivalent ways to implement BLOCKHASH:
The fact that (1) and (3) are possible is nice, because it removes the long block header history from the "de-facto state"; now, only knowing the last 8 headers and the state is sufficient for fully validating and processing blocks. The fact that (2) is possible is nice, as it means that there is low effort required for existing clients to switch over. |
Summary of my comments:
|
Have you thought about back-filling the old blockhashes in a second hard-fork? In the first hard-fork, a method is added for the SYSTEM user to backfill the historical hashes, and then in the second hard-fork, the actual back-filling transactions are inserted. Another solution to the back-filling is to allow anyone to submit the block headers so that the contract can hash them, check the block hash and populate the prev hash from the header. The cost is in historical block headers effectively repeated in the block bodies, which would currently be ~500M extra disk space + gas to populate all those headers. This solution does not require hard fork though |
Please merge this as Draft with number 210 as agreed in All Core Devs Meeting #34. |
This is a courtesy notice to let you know that the format for EIPs has been modified slightly. If you want your draft merged, you will need to make some small changes to how your EIP is formatted:
If your PR is editing an existing EIP rather than creating a new one, this has already been done for you, and you need only rebase your PR. In addition, a continuous build has been setup, which will check your PR against the rules for EIP formatting automatically once you update your PR. This build ensures all required headers are present, as well as performing a number of other checks. Please rebase your PR against the latest master, and edit your PR to use the above format for frontmatter. For convenience, here's a sample header you can copy and adapt:
|
Re-posting here (from gitter AllCoreDev) -- because I'm not sure where the discussion should go
|
* Create blockhash_refactoring.md Stores blockhashes in the state, reducing the protocol complexity and the need for client implementation complexity in order to process the BLOCKHASH opcode. Also extends the range of how far back blockhash checking can go, with the side effect of creating direct links between blocks with very distant block numbers, facilitating much more efficient initial light client syncing. * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Rename blockhash_refactoring.md to eip-210.md
The new EIP-210 code would return out of gas if the current block number is
Is this intentional? |
No. #1094. |
Stores blockhashes in the state, reducing the protocol complexity and the need for client implementation complexity in order to process the BLOCKHASH opcode. Also extends the range of how far back blockhash checking can go, with the side effect of creating direct links between blocks with very distant block numbers, facilitating much more efficient initial light client syncing.
When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-X.md