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

EVM-C v3 #112

Merged
merged 20 commits into from
May 10, 2017
Merged

EVM-C v3 #112

merged 20 commits into from
May 10, 2017

Conversation

chfast
Copy link
Member

@chfast chfast commented Jan 18, 2017

PoC of #110

In cpp-ethereum ethereum/aleth#3510 the state test running time goes down by ~2-5%.

@@ -19,19 +20,21 @@ struct evm_uint160be address(struct evm_env* env)
static void query(union evm_variant* result,
struct evm_env* env,
enum evm_query_key key,
const union evm_variant* arg) {
Copy link
Member

Choose a reason for hiding this comment

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

Why is it better not to have this union?

Copy link
Member Author

Choose a reason for hiding this comment

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

Previously this function was used to get other data (e.g. EXTCODESIZE -- the argument was the address, now address is explicit argument, BLOCKHASH -- the argument was int64 number of the block). Now the only possible argument is the storage key for SLOAD, so the type has changed from evm_variant to evm_uint256be.

@@ -41,6 +44,7 @@ static void query(union evm_variant* result,

static void update(struct evm_env* env,
enum evm_update_key key,
const struct evm_uint160be* addr,
Copy link
Member

Choose a reason for hiding this comment

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

Why is there addr and arg1, arg2?

Copy link
Member Author

Choose a reason for hiding this comment

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

So update callback supports SSTORE (arg1: key, arg2: value), LOG (arg1: topics, arg2: data) and SELFDESTRUCT (arg1: address). See example implementation in cpp-ethereum: https://github.com/ethereum/cpp-ethereum/blob/4cb9b1085a11a04d5e6f6429df3681eaab2480fd/libevm/JitVM.cpp#L92-L112.

Because logs are not state changes per se, we can create another callback function for logs only (I forgot I wasn't happy about this). But in the end SSTORE and SELFDESTRUCT needs different types of arguments so evm_variant will be needed...

Copy link
Member

Choose a reason for hiding this comment

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

But that means two evm_variant args should be enough?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. For SSTORE you have to provide address, key and value because the address of the currently executed account is only in the message. The "host" application does not need to remember what account EVM is going to change. This is abstraction what is introduced with message / tx data / state separation. Go and Python have internal API that reflects this already.

Copy link
Member

Choose a reason for hiding this comment

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

Do we have any recommendations how the VMs should ensure that unauthorised SSTORE doesn't happen?

Copy link
Member Author

Choose a reason for hiding this comment

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

VM should use the address from a message in this case, unless it wants to implement internal calls by itself...

Copy link
Member

Choose a reason for hiding this comment

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

Maybe in that case we should also pass the current call context? Talking a bit blindly here, as haven't done the client side yet.

Copy link
Member Author

Choose a reason for hiding this comment

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

All we need (at the moment) to manipulate or query the state (read: the map of all accounts) it an account address. All other data in a message (call context) is volatile and has not use for the state, i.e. value, input data, gas limit, etc.

evm_call_fn call_fn;
evm_get_tx_context_fn get_tx_context_fn;
evm_get_block_hash_fn get_block_hash_fn;
Copy link
Member

Choose a reason for hiding this comment

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

Why is the block hash not part of the state? Because it is being offloaded to a contract?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. BLOCKHASH is not query about the state exactly and it does not match the query() function callback where you always have to provide the address of an account you query about. In the end it is not transaction data, nor query about accounts... so it got its own callback function.

Metropolis changes are no going to help because we are not going to remove (or deprecate) BLOCKHASH opcode. However, EVM implementation could actually use query() function to get needed information, instead of relying on dedicated callback function.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds reasonable.

(Note, the opcode will actually be a call to the contract.)

@@ -41,11 +45,49 @@ struct evm_uint256be {
};

/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
/// TODO: Rename to "address".
Copy link
Member

Choose a reason for hiding this comment

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

Agree with this one :)

Copy link
Member Author

Choose a reason for hiding this comment

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

After we finish with functional changes I plan to do some renaming here and there...


llvm::Value* RuntimeManager::getSender()
{
return m_dataElts[RuntimeData::Caller];
Copy link
Member

Choose a reason for hiding this comment

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

Can we use the same name, either sender or caller?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes.

@axic
Copy link
Member

axic commented May 4, 2017

I like the split of state / tx context / call context, but not sure which is better for VMs.

@axic
Copy link
Member

axic commented May 5, 2017

The documentation in evmc.h should be updated: https://github.com/ethereum/evmjit/blob/evmc-v3/include/evm.h#L233

Most of these fields were removed.

@chfast
Copy link
Member Author

chfast commented May 8, 2017

Docs updated.

@chfast
Copy link
Member Author

chfast commented May 10, 2017

@gumb0 approved cpp-ethereum side. Is this one ready to land as well?

@chfast chfast merged commit 40151fd into develop May 10, 2017
@chfast chfast deleted the evmc-v3 branch May 10, 2017 22:15
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