ethereum/EIPs

Question on EIP3: CALLDEPTH

janx opened this issue · 6 comments

janx commented

link: https://eips.ethereum.org/EIPS/eip-3

IMO it's a good practice to check return value of callee if consequential operations is dependent and critical, if so what's the advantage of checking CALLDEPTH instead of return value?

Another point is, even if you use CALLDEPTH to guard stack overflow, you may still need return value guard in case there's other errors, thus leads to more verbose code?

CALLDEPTH seems like it will ruin encapsulation in a lot of ways. msg.sender is an elegant abstraction

It seems CALLDEPTH is trying to solve a problem that could be solved more simply by some kind of error bit in the EVM state. Maybe OOG can be retrofitted to use an error bit as well.

I similarly don't see the value in using CALLDEPTH instead of an error bit, but I did advocate for something similar, for different reasons, a year ago, and still would now: https://www.reddit.com/r/ethereum/comments/2hu2fq/proposal_for_new_opcodes_callstack_and/

axic commented

The current version is reachable at: https://eips.ethereum.org/EIPS/eip-3

@holiman it seems you have never addressed the questions above.

Is it still relevant? If not, should it be marked "Rejected"? If yes, what would it take to implement it?

While not fully relevant, it does help in the context of ewasm implementing evm2wasm (see ewasm/design#138)

Earlz commented

The CALLDEPTH opcode would make it trivial to implement a guard preventing uncontrolled reentrancy into the contract while still allowing self-calls. With the new net gas metering for storage, I think it'd even be fairly cheap

Basically just a storage variable expectedDepth. expectedDepth would be incremented when calling itself, and each function needing a reentrancy guard would check expectedDepth matches CALLDEPTH. When the self-call function returns, decrement expectedDepth. If implemented properly, expectedDepth is never anything but 0 upon contract termination (except in case of error, where this state would be reverted anyway). It would need some special case checking for when the contract is initially called with CALLDEPTH > 0, potentially another storage variable or flag saying "execInProgress" or similar, but should be easily doable.

The only other existing way to implement such a guard is not suitable for all cases. It can be done by checking sender == origin, but this prevents contract called contracts from preventing reentrancy as well as self-calls. It's also possible to use a simple storage mutex, but that also prevents self-calls.

I see no way to have this kind of reentrancy guard functionality without CALLDEPTH and I don't really understand why this EIP is deferred with very little discussion and with only one narrow use case in mind

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.