-
Notifications
You must be signed in to change notification settings - Fork 737
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
common/block/blockchain: genesis refactor #1916
Conversation
Codecov Report
Flags with carried forward coverage won't be shown. Click here to find out more. |
1c65eb5
to
7ca78aa
Compare
Thanks so much. 🙂 I think I am a fan of continuing on this. |
7ca78aa
to
30068c6
Compare
Have to look into two ci issues, vm-api browser run timing out (taking too long?) and client cli connection. The PR can still be reviewed for everything else meanwhile. |
6e7785d
to
a84cc40
Compare
This is ready for review :) |
Oh, 1 commit 😬 (thanks a thousand times, otherwise totally great that you got through this!!!). This will be a bit harsh for review, would have preferred to have this step-by-step on such a large change set. But will try my best. 😋 |
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.
Ok, this is such a convicing refactor (and it actually looks good on all fronts! 🙂 👍), I will directly take this in.
So so great, now seeing this I totally love the outlook (even more) of finally having these light-weight lower level libraries. Especially for tx this is a great win.
Will merge.
) { | ||
baseFeePerGas = BigInt(this._common.genesis().baseFeePerGas!) | ||
} | ||
} |
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.
Ok, I wondered a bit along seeing this how much people are using this functionality and if they will or will not miss this, but: I guess in case this is requested, we can very well add some less intrusive helpers (e.g. - similar to what we thought about for Common, allow passing in a genesis json + stateRoot + hash to create a block), which would be a non-breaking addition. So I think we can go with this.
const rlp = Buffer.from(testDataGenesis.test.genesis_rlp_hex, 'hex') | ||
const hash = Buffer.from(testDataGenesis.test.genesis_hash, 'hex') | ||
const block = Block.fromRLPSerializedBlock(rlp, { common }) | ||
st.ok(block.hash().equals(hash), 'genesis hash match') |
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.
Ah, nice replacement. 🙂
* } | ||
* ``` | ||
*/ | ||
genesisState?: GenesisState |
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.
Ok, just followed this along just to get some confirmation: so if one now would want to run a VM with/upon some custom genesis state, one would create a Blockchain object first with this genesis state and passes this into the VM along initialization. Seems a reasonable replacement to me for this eventual use case.
@@ -115,7 +143,8 @@ export default class Blockchain implements BlockchainInterface { | |||
db: LevelUp | |||
dbManager: DBManager | |||
|
|||
private _genesis?: Buffer // the genesis hash of this blockchain | |||
private _genesisBlock?: Block /** The genesis block of this blockchain */ |
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 is actually also a nice replacement to have the Block
here and not level down to just the hash (why?).
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.
we have the whole block now so I figure it's nicer to cache it, as the hash can still be accessed, and it makes life easier e.g. in the client chain
that returns genesis()
as the genesis block. there might be more uses for the other fields in the future.
stateRoot = Buffer.from( | ||
'd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544', | ||
'hex' | ||
) |
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.
👍
Great optimization!
const blocks: Block[] = [] | ||
const genesisBlock = Block.genesis({ header: { gasLimit: 8000000 } }) |
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.
Oh, impressive, that this can be so easily replaced in the tests by the generic functions, seems specifically using genesis()
wasn't necessary at all here in most cases?
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.
heh yeah since the block number still defaults to zero, we weren't losing much, as there were not very many cases where we needed the actual genesis params.
}) | ||
return genesisParams | ||
get genesis() { | ||
return this.blockchain.genesisBlock() |
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.
👍
max === 0 ? Buffer.from([]) : intToBuffer(max), | ||
skip === 0 ? Buffer.from([]) : intToBuffer(skip), | ||
!reverse ? Buffer.from([]) : Buffer.from([1]), | ||
], |
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.
Just out of interest and because I can't spot right away: why did this code needed to change in this context?
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 is related to the RLP v3 changes, not sure why it just popped up in my PR, but when doing bufArrToArr
we need all fields to be Buffer, otherwise if it is is a plain number it didn't convert correctly to Uint8Array.
common.setHardforkByBlockNumber(0) | ||
return BlockHeader.fromHeaderData(headerData, { common }) | ||
} | ||
|
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.
Ugh. This is just falling off the cliff? How great is this? 😀
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.
yeah! some great simplifications through the process here
} | ||
return this._calcForkHash(hardfork) | ||
if (!genesisHash) throw new Error('genesisHash required for forkHash calculation') | ||
return this._calcForkHash(hardfork, genesisHash) | ||
} |
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.
That's a great modified forkHash
version.
a84cc40
to
803300a
Compare
Rebased this via UI after local test rebase. |
This PR works on the ideas presented in #1833, mainly #1833 (comment) and #1833 (comment).
This PR:
stateRoot
andhash
from CommongenesisStates
from Common to BlockchainVM.runBlockchain()
BlockchainTestsRunner
where we now directly putBlocks and run the blockchain iteratorI haven't run the test suite yet to fix failing tests as I wanted some confirmation that we want to proceed on this path before working on the final touches.
The only downside so far (that I see) is that when setting up a custom chain you used to only need a very portable common but now you have to additionally pass the genesis states into blockchain, but this was easy enough to adjust to in the client by passing an optional blockchain when custom genesis states (or geth genesis) is provided.
Removing
stateRoot
andhash
was also tricky in a few places but I think I overcame the challenges.