Storage nodes are not being marked as removed when the contract is destroyed. #141
Closed
opened 2022-03-10 03:27:44 +00:00 by i-norden
·
3 comments
No Branch/Tag Specified
v5
fix/pin-eth-typing
fix/pin-dlv-version
ian/tracing
payments
v5-go-upgrade
v4
release-v4.1.7-alpha
ian_v4
release-v4.1.4-alpha
release-v4.1.2-alpha
sharding
release-v4.1.0-alpha
master
v5.3.0-alpha
v5.2.0-alpha
v5.1.2-alpha
v5.1.1-alpha
v1.11.6-statediff-v5
v4.1.8-alpha
v4.1.7-alpha
v4.1.6-alpha
v4.1.5-alpha
v4.1.4-alpha
v4.1.3-alpha
v4.1.2-alpha
v4.1.1-alpha
v4.1.0-alpha
v4.0.6-alpha
v4.0.5-alpha
v4.0.4-alpha
v4.0.3-alpha
v3.2.2
v4.0.2-alpha
v3.2.1
v3.2.0
v4.0.1-alpha
v4.0.0-alpha
v3.1.0
v3.0.0
v2.0.0
v0.3.9
v0.3.8-alpha
v0.3.7-alpha
v0.3.6-alpha
v0.3.5-alpha
v0.3.4-alpha
v0.3.3-alpha
v0.3.2-alpha
v0.3.1-alpha
v0.3.0-alpha
v0.2.0-alpha
v0.1.0-alpha
v0.0.13
v0.0.12
v0.0.11-alpha
v0.0.10-alpha
v0.0.9
v0.0.8
v0.0.7
v0.0.6
v0.0.5
v0.0.4
v0.0.3
v0.0.2
v0.0.1
Labels
Clear labels
Epic
Integration tests
bug
critical
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
v5
wontfix
Copied from Github
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Something isn't working
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
Good for newcomers
Extra attention is needed
This doesn't seem right
Further information is requested
This will not be worked on
An issue or PR manually copied from GitHub.
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
Reviewed
Confirmed
Issue has been confirmed
Reviewed
Duplicate
This issue or pull request already exists
Reviewed
Invalid
Invalid issue
Reviewed
Won't Fix
This issue won't be fixed
Status
Abandoned
Somebody has started to work on this but abandoned work
Status
Blocked
Something is blocking this issue or pull request
Status
Need More Info
Feedback is required to reproduce issue or to continue work
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cerc-io/ipld-eth-server#141
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Discovered by Ashwin and his team.
This causes a bug in ipld-eth-server:
If a contract deployed at some address
addrthat has a non-empty storage triesis destroyed at some blocknand then a contract (same or different) is redeployed ataddr(using CREATE2 opcode) at some blockmif we perform the query currently used in RetrieveStorageAtByAddressAndStorageSlotAndBlockHash at some blockm+x; where x>=0it will behave as if the new contract inheritedsas its initial state.In particular, if the specific storage leaf key being queried doesn't exist in the redeployed contract's storage trie at
m+xbut it did exist ins, the query will incorrectly return the value held at that key insinstead of an empty value.Fixes
During statediffing
This could be fixed on the indexing end, by adjusting the statediffing code to iterate
sand insert a "removed" node-type entry toeth.storage_cidsat blocknfor every node in the trie when generating the statediff betweenn-1andn. This would be done here. Having to iterate the entire storage trie is potentially very expensive, and this wouldn't fix the data that has already been processed into Postgres.Adapt the query
Alternatively, the query used here could be adjusted to account for this issue.
was_state_leaf_ever_removed) for checking if a node has ever been removed for a specificstate_leaf_key, returning the blockheight(s) it was removed at if so.retrieve_storage_by_address_and_storage_slot_and_blockHash) that first callswas_state_leaf_ever_removedto check if the storage key was ever removed. If it wasn't, it proceeds with the current access pattern. If it was, it finds the height at which it was (most recently) removed and limits its query toeth.storage_cidsrecords above this block height.This would add additional overhead to the query. This also only fixes this symptom, not the underlying issue. This issue will produce a similar symptom when, for example, trying to create a new storage snapshot from a previous snapshot + all the interim diffs and we would require an adapted query for that as well.
Post-processing of data in Postgres
This issue could also be fixed in post-processing, the algorithm for this would look like:
eth.state_cidsrecords that correspond to a contract destructionThat gets you all removed leaf nodes and the block heights they were removed at, but that includes EOAs and contracts.
To figure out if the removed leafs contained contracts, you need to find the latest non-removed-type
entry for those
state_leaf_keys and check if they contain a non-"zero" storage root ("zero" value of root iskeccak256(rlp([]byte{}))).eth.storage_cidsrecord at everystorage_pathin the trie for those contracts$1 =
state_leaf_keyfor removed contract, found in step 1$2 =
block_numberwhere the contract was destroyed, found step 1eth.storage_cidsrecords withnode_type = 3for all of the records found in the above query.Proposal
Make the updates described in 1) to fix newly indexed data. Use the approach described in 3) to fix the existing data in Postgres.
These contract destructions aren't very frequent, so the performance impact on the head-tracking process should be minimal in aggregate but it could introduce significant latency in the processing of the specific statediffs where large contract destructions do occur. Due to the infrequency, the historical processing required would be sparse and with the index on
node_typeit should be fast to find the (relatively few) contracts we need to fix the issue for.Some notes from discussion today:
Ashwin and his team have identified the problem described here extends to the storage trie. To alleviate this, we need to introduce a new "moved" node type for representing, in our PostgresDB, leaf nodes that have been moved to a new path vs leaf nodes that have been removed altogether.
Tasks:
Closing this as we no longer need to post-process v4 as we are moving to v5, and the missing integration test scenario is no longer relevant in v5 since we don't index intermediate nodes so there would be no need to distinguish between "moved" vs "removed", although we do still need better testing in place for when accounts or slots are removed e.g. https://github.com/cerc-io/tx-spammer/issues/18