Closed JakeOShannessy closed 6 years ago
Tests have been added to ensure that logs are properly added on chain and can be retrieved. We still need to add a proper topic. Maybe just a simple hash of a logical name.
@JakeOShannessy: For topic encoding, we could use a hash, ASCII or utf8. If ASCII, we get 35 symbols, which would suffice.
Possible labels:
I think the former is good.
Tests have been heavily refactored in this PR. They now rely on a module structure, which is more verbose but I've found to be much easier to work with. Many tests are split and labelled. This leads to some repetition. but makes the test output clearer.
@Latrasis Those labels look good to me, I agree that the first is better. What are your thoughts on tiers? We could have the format ["KERNEL", "SSTORE"]. This means in the future if there are many different kernel logs, we can easily retrieve them all or just a subset (just the hierarchical topic structure). Essentially we would be replacing the underscore with an Ethereum-aware structure.
I've pushed using a hash of KERNEL_SSTORE for now. I think we should try and merge this into master. Currently there are two failing tests due to the storage protection checker not recognising the log routines. These tests will need #12 to be addressed first in order to adequately rebuild that checker.
Is there anything else holding this one up?
When this is merged #1 and #11 can be closed.
@JakeOShannessy: Format sounds good, my preference would be to use the raw ASCII instead a keccak hash for namespaces if we can.
@Latrasis Raw ASCII makes sense for readability. I went with the hash for the following reasons, let me know what you think:
Might be worth making an issue to discuss other logging topics too.
This PR adds logs to all store calls (along with the protection). This works on chain and passes all tests, although I haven't tested making good use of these logs. I've added some notes in the docs folder on this repo, and I've reproduced that here so you can have a look.
Logging of Storage Calls (On-Chain)
In order to track the changes to storage of over time (over transactions), logs are inserted at each SSTORE call. There are 5
LOG
opcodes that append a log to a number of topics.LOG0
- Log to no topics.LOG1
- Log to 1 topic.LOG2
- Log to 2 topics.LOG3
- Log to 3 topics.LOG4
- Log to 4 topics.LOG0
expects there to be 2 arguments on the stack. These two arguments are:For each of the other
LOGN
calls an additionalN
stack items are expected below these items to define the topics to which this log will be published. For example: aLOG4
call expects the stack to be as below:Note the use of memory buffer arguments. Any call to
LOG
requires using memory to pass the data. As we are transforming programs of unknown memory layout, and of an unknown memory allocation scheme, we are unable to allocate out own memory in the general case. We cannot even assume that the Solidity memory allocator is present.To get around this problem we write to arbitrary points in memory to create a buffer for out
LOG
call. Before we write to this buffer, we load the values onto the stack (using two stack spaces). After we are finished with this buffer, we can write those values back into those memory locations from the stack, returning it to its original state. We will arbitrarily use the addresses 0x60 and 0x80 (which are contiguous at 32 bytes) for ourLOG
calls.We want to store two pieces of information:
When consuming this information we would be interested in the procedure id and the capabilities of that procedure, but that information is not available at preprocessing time. Instead, with the contract address we should be able to determine these properties later. The data is therefore a fixed length of 50 bytes. The first 20 of which is the contract address, and the next 32 of which is the storage key with which
SSTORE
is being called.This is the general procedure we want to follow for each logging call (this does not cover the storage call or its protection, simply the logging):
Translated into opcodes: