Skip to content

Conversation

@aarlt
Copy link
Collaborator

@aarlt aarlt commented Nov 25, 2020

No description provided.

// Trace:
// Memory dump:
// 20: 9999990900000000000000000000000000000000000000000000000000000000
// 20: 0000000000000000000000000000000000000000000000000000000009999999
Copy link
Contributor

Choose a reason for hiding this comment

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

All of these tests would make more sense with having mstore(0, <some random number>) mstore(32, <some random number>) at the beginning to clobber the space the polyfill is writing to.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree. We should improve the ewasm translation tests. I think the memory there should not be initialized with zero's. So we could easily check how many bytes where written by the e.g. polyfills.

Copy link
Contributor

Choose a reason for hiding this comment

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

It should be initialised to zeroes, as it is done so on wasm and evm.

However we should change the tests to explicitly make those slots dirty.

Copy link
Contributor

Choose a reason for hiding this comment

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

This PR still waits for adding these clobbering instructions to these files.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@axic Is 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff good enough for that or do you think it should actually be something looking more random?

Copy link
Contributor

Choose a reason for hiding this comment

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

So actually instead of sstore() we wanted to use mstore() for clobbering, however that starts at actual memory 0x40 and the lower 0x40 bytes are used as scratch space in the translators:

+++ b/test/libyul/ewasmTranslationTests/origin.yul
@@ -1,9 +1,13 @@
 {
+  mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
+  mstore(32, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
   sstore(0, origin())
 }
 // ----
 // Trace:
 // Memory dump:
 //     20: 0000000000000000000000000000000000000000000000000000000033333333
+//     40: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+//     60: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
 // Storage dump:
 //   0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000033333333

I think we should just remove sstores from this PR and try to figure out clobbering later.

@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from 386d0ee to cfc4c09 Compare November 26, 2020 14:22
@aarlt aarlt requested a review from axic November 26, 2020 14:31
@axic
Copy link
Contributor

axic commented Nov 30, 2020

Need to rebase due to other polyfill changes were merged.

@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from cfc4c09 to 3a7f5bd Compare November 30, 2020 23:28
@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from 3a7f5bd to b782b43 Compare December 1, 2020 16:45
@leonardoalt
Copy link

@axic was that an "approve after rebase"?

function callvalue() -> z1, z2, z3, z4 {
eth.getCallValue(0:i32)
z1, z2, z3, z4 := mload_internal(0:i32)
z3 := i64.load(8:i32)
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not need a bswap?

Copy link
Collaborator

@cameel cameel Jan 26, 2021

Choose a reason for hiding this comment

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

@aarlt Yeah, mload_internal() does the endianness swap internally. Why doesn't it need it? And why for example balance() still does?

Copy link
Collaborator Author

@aarlt aarlt Jan 28, 2021

Choose a reason for hiding this comment

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

I checked the hera implementation EthereumInterface::eeiGetCallValue(uint32_t resultOffset) is using storeUint128(m_msg.value, resultOffset); to write the actual value. storeUint128 uses storeMemoryReverse to store that value. That means the value should be big-endian in memory and therefore the usage of bswap should be needed here.

The strange thing is that the tests only run correctly, if we don't do the byte-swap.

So I thought that we store the value wrong within the call polyfill. After checking I saw we store it correctly, we retrieve the value and use mstore_internal. That means we definitely should have the value as big-endian in memory:

	let v1, v2 := u256_to_u128(c1, c2, c3, c4)
	mstore_internal(32:i32, 0, 0, v1, v2)
	// ...
	x4 := i64.extend_i32_u(eth.call(g, 12:i32, 32:i32, to_internal_i32ptr(d1, d2, d3, d4), u256_to_i32(e1, e2, e3, e4)))

So I checked then what hera is actually doing in eeiCall. Here we load the memory correctly call_message.value = loadUint128(valueOffset);, during the load we also swap big-endian back to little-endian, because loadUint128 uses loadMemoryReverse.

However, I noticed that eeiCall gets never executed. So I took a look at the ExecutionFramework, especially ExecutionFramework::sendMessage. Here we setup the message value with message.value = EVMHost::convertToEVMC(_value);. And looking at message.value, it is already big-endian (the higher addresses store smallest parts of the value). That means if this value is stored using storeUint128 via eth.getCallValue the bytes will get swapped again to little-endian. Thats why I noticed that the bswap is not needed here.

I guess that the message values need to be in big-endian, before they arrive at an vm. If we would change it here, the current tests via evm-one would also fail. I think the interaction with an evm from the test-framework perspective should be identical, for the evmone- and the ewasm-case. So I think it is a problem in hera.

I will take a look what is the best option to fix hera tomorrow.

@axic would you agree that this is a hera problem?

Copy link
Contributor

Choose a reason for hiding this comment

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

From https://github.com/ewasm/design/blob/master/eth_interface.md:

u128: a 128 bit number, represented as a 16 bytes long little endian unsigned integer in memory

getExternalBalance
Gets balance of the given account and loads it into memory at the given offset.

Parameters

addressOffset i32ptr the memory offset to load the address from (address)
resultOffset i32ptr the memory offset to load the balance into (u128)

The byteswapping in storeUint128 is because EVMC considers the value big endian, so this swaps it for wasm.

@chriseth
Copy link
Contributor

chriseth commented Dec 7, 2020

@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch 4 times, most recently from 32c349c to 131842d Compare December 21, 2020 13:32
@aarlt
Copy link
Collaborator Author

aarlt commented Dec 28, 2020

@axic Please review

@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from 131842d to 09bfa94 Compare January 19, 2021 01:15
@leonardoalt
Copy link

Ah, tests here are also failing with "Invalid code generated", wondering if it's something common between the 2 PRs

@aarlt aarlt force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from 09bfa94 to 77213c0 Compare January 19, 2021 18:03
@aarlt
Copy link
Collaborator Author

aarlt commented Jan 19, 2021

@leonardoalt #10686 uses some features that are not yet ready in ewasm. I just disabled the ewasm execution of these tests.

Copy link
Collaborator

@cameel cameel left a comment

Choose a reason for hiding this comment

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

What is the purpose of this PR? Looking at the title I expected that it implements the three polyfills but I see that polyfills are already implemented and you seems to be just changing the endianness of their results. So is this actually a bugfix?

If changing the endianness is what it's meant to do then the code looks fine now. I did not find any actual problems.

@aarlt
Copy link
Collaborator Author

aarlt commented Jan 22, 2021

So is this actually a bugfix?

If changing the endianness is what it's meant to do then the code looks fine now. I did not find any actual problems.

@cameel Exactly. This PR is a bugfix. The original polyfills where implemented without any real ewasm vm. After we have plugged in hera, we noticed that the endianess was implemented wrong.

@cameel
Copy link
Collaborator

cameel commented Jan 26, 2021

@aarlt Ok. I'd suggest renaming in then since the title is the only thing you have for context when starting to review it :)

cameel
cameel previously approved these changes Jan 26, 2021
Copy link
Collaborator

@cameel cameel left a comment

Choose a reason for hiding this comment

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

I think this is good to go.

@axic, @leonardoalt, @chriseth It looks to me like all your comments were addressed. Is there anything else to do here?

@cameel cameel dismissed their stale review January 26, 2021 13:34

Actually, there's still a pending question about bswap in value().

@aarlt
Copy link
Collaborator Author

aarlt commented Jan 28, 2021

We should add a test that gets called with a value from the test framework and triggers another call with value to another function. Not sure whether we have such test already.

@chriseth
Copy link
Contributor

chriseth commented Feb 1, 2021

Needs rebase.

@leonardoalt
Copy link

Still needs rebase.

@leonardoalt
Copy link

Ping @aarlt

@cameel
Copy link
Collaborator

cameel commented Apr 21, 2021

We discussed this today on the call. This is basically just blocked by #10406 (comment) (and also needs a rebase). But we decided that we could just merge it as is and deal with problems later when/if we encounter them.

@axic axic force-pushed the ewasm-polyfill-callvalue-gasprice-difficulty branch from 77213c0 to 73b804a Compare April 23, 2021 14:54
@axic
Copy link
Contributor

axic commented Apr 23, 2021

Removed the sstore and rebased. Since we do not have #10356 merged, I did not try forcing which tests would work now, I think we can do that separately?

@axic axic merged commit 55577cb into develop Apr 23, 2021
@axic axic deleted the ewasm-polyfill-callvalue-gasprice-difficulty branch April 23, 2021 15:36
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.

7 participants