Skip to content
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

revm: Return bytes in Create calls #289

Merged
merged 1 commit into from
Dec 12, 2022

Conversation

ngotchac
Copy link
Contributor

@ngotchac ngotchac commented Dec 8, 2022

In create_inner, let b = Bytes::new(); was always returned, without ever being touched. The create calls should return the deployed contract bytecode.

This might relate to #269 ?

@rakita
Copy link
Member

rakita commented Dec 9, 2022

It shoud return empty if everything is okay, and return something if create fails, like here:

interpreter.return_value(),

@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

It shoud return empty if everything is okay, and return something if create fails, like here

I'm not sure I understand why do you think that? In geth & erigon at least, an eth_call with a contract deployment input always return the deployed bytecode:

curl --data '{"method": "eth_call","params":[{"data": "0x60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029"}, "latest"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545

(the input being the tx input of the WETH deployment tx : https://etherscan.io/tx/0xb95343413e459a0f97461812111254163ae53467855c0d73e0f1e7c5b8442fa3)

And this actually makes sense, since every contract deployment always end with RETURN to let the EVM know where the contract code is.

This feature is super useful to know the deployed bytecode of a contract without deploying it. Or even to run some EVM code like so:

interface ERC20 {
    function balanceOf(address) external returns(uint256);
}

contract Tester {
    constructor(address[] memory tokens) {
        uint256[] memory balances = new uint256[](tokens.length);

        for (uint256 i = 0; i < tokens.length; i += 1) {
            balances[i] = ERC20(tokens[i]).balanceOf(msg.sender);
        }

        uint256 len = (tokens.length + 1) * 32;
        assembly {
            return(balances, len)
        }
    }
}

and doing an eth_call with the deployment input will return the tokens balances.

@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

Here's the part in go-ethereum in evm that returns the deployed code BTW: https://github.com/ethereum/go-ethereum/blob/890e2efca2111c790c6d5eb55e29981816ee1fe9/core/vm/evm.go#L404-L499

@rakita
Copy link
Member

rakita commented Dec 9, 2022

Sorry for the confusion, I meant revm returns only error bytes, having bytecode returned is indeed desirable.
wdyt about returning it here, if exit is return_ok fetch bytes from JournledState::state and return it?

@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

Oh right, OK I totally misunderstood aha! Why not returning them directly in create_inner though? As they are already available, without the need to re-fetch them

@rakita
Copy link
Member

rakita commented Dec 9, 2022

hm you are right, Bytes is just a pointer to static vec, clone is fast.

just move this code inside return_revert and _

interpreter.return_data_buffer = return_data;

@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

just move this code inside return_revert and _

You mean return_ok and _ ?

@rakita
Copy link
Member

rakita commented Dec 9, 2022

https://github.com/bluealloy/revm/pull/289/files#diff-1d478ba44ccc56e3b1142bd3723bf97f3e254c25dd18323481aedadce0803e91L549

If create reverts, it can in that case return the return data, it should be return_revert and _

But return_ok should set it to to empty bytes.

@ngotchac ngotchac force-pushed the ngotchac/fix-create-return branch from 798e0e0 to 2656f70 Compare December 9, 2022 14:12
@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

Oh right, gotcha! So yeah I fixed that, I actually only check for Revert, so it's not added for CallTooDeep or OutOfFund

@rakita
Copy link
Member

rakita commented Dec 9, 2022

It is best to add it to all not just for revert, and we would need to clear past return_data_buffer with interpreter.return_data_buffer = Bytes::new() if it is return_ok

FatalExternalError is panic like error, it will stop execution and propagate to initial call

@ngotchac ngotchac force-pushed the ngotchac/fix-create-return branch from 2656f70 to 37a6032 Compare December 9, 2022 18:51
@ngotchac
Copy link
Contributor Author

ngotchac commented Dec 9, 2022

All right, it's done!

Copy link
Member

@rakita rakita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! ty

@rakita rakita merged commit fd01083 into bluealloy:main Dec 12, 2022
@ngotchac ngotchac deleted the ngotchac/fix-create-return branch January 2, 2023 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants