-
Notifications
You must be signed in to change notification settings - Fork 107
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
Mising operations of Aristo: handle sidechain in memory #2260
Comments
Based on what we have today in the codebase, here's a sketch of a design that should be correct, albeit inefficient - it's useful as a starting point however and it is based on the idea of doing exactly what In short, we would move the local local variables of type ForkedChainDb = object
dbtx: ...
coredb: CoreDbRef
blocks: Table[Hash256, EthBlock]
head: Hash256
safeHead: Hash256
heads: seq[Hash256]
base: Hash256 This object would keep track of what blocks have been processed "so far" and obviously would have appropriate lists of blocks, parent relationships and so on - the fields in this object are for illustration only. We'd have two operations -
proc addBlock(chain: ForkedChain,blk: EthBlock): Result =
if chain.dbtx == nil: chain.coredb.createTransaction()
if processBlock(blk, ...).iserr:
chain.dbtx.rollback()
# recreate in-memory state
for blk in chain.blocks: addBlock(blk)
return
chain.blocks.add blk
heads.add(rlpHash(blk))
heads.del(blk.parentRoot) # approximately
proc updateHead(chain: FC, head: Hash256, finalized: Hash256) =
chain.head = head
chain.finalized = finalized
let newbase = chain.blockat(min(chain.finalized.blocknubmer, head.blockNumber - 128))))
if chain.base != newbase:
chain.dbtx.rollback()
# Replay the blocks from our local database
persistBlocks(chain.blocks[chain.base..newbase])
chain.blocks.del(chain.base..newBase)
# recreate the in-memory state
for blk in chain.blocks: chain.addblock(blk)
chain.base = newBase Of course, the above is a sketch, but this would be enough to correctly follow the chain and respond to most json-rpc queries (which would call |
Copied from discord discussion:
One of the test case in test_blockchain_json doing something like this:
nimbus-eth1/tests/fixtures/eth_tests/BlockchainTests/TransitionTests/bcHomesteadToDao/DaoTransactions.json
(several other failing test cases also doing similar things)
where D is default chain, and H is side chain. Block with a 'X' is an invalid block. When executing block H1, there is an error message like this because H1 request for genesis stateRoot but cannot find it anymore.
comments from @arnetheduck :
This is something we should be able to support with the pure in-memory option - ie as long as D4 is the finalization point, it's supported, but that also means that only D4 has been written to disk.
so it sounds like it's a set of operations that we need are not captured in the current API design, but for the sake of argument, here's how it can be done (based on what I've seen in persistBlocks at least:
when processing D1, we open transaction T1
then for D2..D15, we open T1.2..T1.15 - ie we never commit T1 - this is the state in which persistBlocks is iterating over the blocks we give it
in this state, we can still process forks because we've not committed T1 and we have all the "diff" layers in memory
Let's say that D4 is finalized. A naive way to implement this is:
roll back all transactions including T1
re-play D1..D4 and commit that
re-play D5..D15 and the remaining branches without committing them
then when D8 is finalized, repeat - this time, H1 is not replayed, because it forks off a finalized section of the graph
The text was updated successfully, but these errors were encountered: