Closed Stebalien closed 1 year ago
SGTM. We want it when?
Now. Want to handle this tomorrow?
This sounds reasonable, especially given that the Ethereum community has noted the many quirks of the SELFDESTRUCT opcode and is potentially looking to eliminate it. So yet another reason to keep those quirks contained in the EVM runtime actor.
Just one question: could you elaborate on the reason why we don't delink the storage HAMT immediately? Can we re-enter within the same transaction with the expectation that storage will still be alive?
Just one question: could you elaborate on the reason why we don't delink the storage HAMT immediately? Can we re-enter within the same transaction with the expectation that storage will still be alive?
Exactly this. Deletion is deferred until the end of the transaction.
Current status: the builtin actors use the latest SDK so this is unblocked, but I haven't made any progress towards actually implementing it. You're good to go vyzo!
Please be aware of behavior of EIP-161 (and if we choose to adopt it, EIP-4747), since there are some cases where there is an auto deletion of "empty" accounts.
We will still be doing userspace deletes for these as well though.
cc @vyzo
edit: we may wish to disregard this since I'm having trouble thinking of an application that would depend on this behavior.
@Stebalien in your refactor of SELFDESTRUCT, can you perform the audit specified here: https://filecoinproject.slack.com/archives/C029MT4PQB1/p1671723226685449.
@Stebalien did we end up committing to a concrete solution here? Is there a sketch PR somewhere that I can take a look to specify in FIP-0054?
First, on SELFDESTRUCT, we record the current origin/nonce in the actor state:
pub struct EvmContractState {
...
tombstone: Option<(ActorId, u64)>,
}
We consider the contact "dead" if, at any point, tombstone
is not none (not null) and tombstone
is not equal to the current origin/nonce.
If the contract is dead, on:
InvokeContract
, we simply return with success (do nothing).GetBytecode
, we return the CID of empty code (ignoring the actual bytecode).GetBytecodeHash
:
On CREATE2/CREATE:
Exec4
method.Finally, the EVM's constructor will allow itself to be called by either the EAM (in which case, it'll delete its own state object and replace it with an entirely new one) or the init actor.
We discussed bypassing the EAM on resurrect, but after writing this all out, I'm nixing that approach as it would require computing the expected EVM address in multiple places.
This also requires changing the EAM's Create2
and Create
signatures to return an Option<Address>
for the "predictable" address, because they may be "resurrecting" an actor.
Our current SELFDESTRUCT operation is incorrect because it deletes the contract immediately. Also, see #1174.
Proposal: Implement SELFDESTRUCT in userspace by:
Resurrect
function that behaves like theConstructor
but:Resurrect
when a user attempts to callCREATE2
and the target actor already exists.Changes WRT Ethereum: