-
Notifications
You must be signed in to change notification settings - Fork 4
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
Add function to check for state node removal. #19
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
-- +goose Up | ||
-- +goose StatementBegin | ||
-- returns if a state leaf node was removed within the provided block number | ||
CREATE OR REPLACE FUNCTION was_state_leaf_removed(key character varying, hash character varying) RETURNS boolean | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
rec RECORD; | ||
BEGIN | ||
FOR rec IN SELECT state_cids.node_type | ||
FROM eth.state_cids | ||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id) | ||
WHERE state_leaf_key = key | ||
AND block_number <= (SELECT block_number FROM eth.header_cids WHERE block_hash = hash) | ||
ORDER BY state_cids.id DESC LIMIT 1 | ||
LOOP | ||
IF rec.node_type = 3 THEN | ||
RETURN TRUE; | ||
END IF; | ||
END LOOP; | ||
RETURN FALSE; | ||
END; | ||
$$; | ||
-- +goose StatementEnd | ||
|
||
|
||
-- +goose Down | ||
DROP FUNCTION was_state_leaf_removed; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Isn't this going to iterate over every entry for this leaf key below the provided block height (hash) before returning FALSE if the leaf was never removed below the provided height?
I think a more performant way to do this might be to simply check for a record with this state_leaf_key and node_type = 3 below the provided height, if it returns empty this contract was not deleted below the height and if such a record exists then it was (a contract can never be destroyed and then deployed to the same address/state_leaf_key, since the contract address is a function of the deploying account's address and the deploying account's nonce- which must increment each time).
Something like
This type of query should, hopefully, be relatively fast now that we have a btree index on the node_type. Adding a
ORDER BY block_number DESC
might speed it up too for the case where a REMOVED node does exist since the REMOVED node would have to be the latest entry and that would force the query planner to search in descending order whereas, I think, otherwise it may not.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, an even better approach building on the train of thought at the end of the last comment: knowing that if a contract was destroyed there can never be entries for that leaf key again, we can search backwards from the provided height/hash and as soon as we find a node with that leaf key we can return TRUE if the node_type = 3 and FALSE if the node_type = 2.
So in a function we can do something like
If the node_type we get is 3 we return TRUE, if its 2 (leaf node) we return FALSE.
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.
And actually the knowledge about being unable to redeploy to the same address is irrelevant... even if we could redeploy, if the latest entry we see for a contract address below a height is REMOVED, then we know the contract is empty at the specified height (it would have to be empty until we saw a new LEAF entry (redeployment) at that address).
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.
Done
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.
Thanks, and just FYI, I am wrong and it is actually possible to deploy a contract to the same address using the
CREATE2
opcode since it uses some supplied salt parameter instead of the account nonce. But in any case, that's irrelevant here as mentioned above.