### EPF - Week 13
This week's progress was a bit slower than expected, although there have been many learnings along the way from both node operations and the Erigon codebase. The biggest hurdle has been that some of the integration work with Erigon turned out to be more complex.
## Integration with Erigon
Last week I started up a Erigon node to be able to start experimenting with an integration. This week most of the time went into trying to setup a small CLI which would interact with the `chaindata` folder from Erigon to construct a StateDB.
There have been a few hurdles along the way and things are still not working as expected. Some high level things:
- Using [DeepWiki](https://deepwiki.com/erigontech/erigon) for exploring the codebase related to the statedb is useful. Some hallucinations, but generally useful tool when used with some skepticism.
- _Hypothesis: me running a full node does not preserve the contract code. Although all documentation I can find seems to point at old block data is removed so working on verifying this. Rationale for thinking this is `stateDB.GetCode(contract)` would never give me any code out_
- As mentioned below, I'll resync and use `rpcdeamon` as a proxy to verify if this is true or not. In retrosepct I should have done that earlier before deleting the previous `datadir`.
- There was no error message when interacting with the StateDB for contracts that should have code. That an address has no code is also a valid case, but it didn't make sense when the transaction in question interacts with a contract.
For context, here is a way to interact with the raw db for a specific transaction
```go
logger := log.New()
db := mdbx.New(kv.ChainDB, logger).Path(chainData).MustOpen()
defer db.Close()
dirs := datadir.New(filepath.Dir(chainData))
agg, err := libstate.NewAggregator2(context.Background(), dirs, config3.DefaultStepSize, db, logger)
if err != nil {
return err
}
err = agg.OpenFolder()
if err != nil {
return err
}
tdb := temporal.New(db, agg)
tx, err := tdb.BeginTemporalRo(context.Background())
if err != nil {
return err
}
defer tx.Rollback()
blockNumber, txNum, err := rawdb.ReadTxLookupEntry(tx, txHash)
```
Then you can use that to interact with the statedb
```go
stateReader := state.NewHistoryReaderV3()
stateReader.SetTx(tx)
stateReader.SetTxNum((*txNum) - 1) // -1 to load the state before the tx
stateDB := state.New(stateReader)
```
So the above should have (in theory at least), be plug and play with the existing interface we had for the tracer and I was able to see calls happening (top level), but none of the `CaptureState` calls were happening.
After some (days of) debugging, I noticed that when reading code from the stateDB
```go
targetCode, err := stateDB.GetCode(*msg.To())
```
It would always be empty. Which is the problem I'm now looking into. To make sure I'm not doing something wrong, once the node is resynced I'll use `rpcdaemon` as a proxy to verify things are in the actual db (`eth_getCode` can be used to verify).
## Opcode support
Most of the ones from last week have been implemented, but it didn't get fully complete because of some of the issues with the interactions with the state db took longer than expected. The code has been pushed to the [same PR](https://github.com/2xic/erigon-risc-v-executable-proof-sourcing/pull/6) as [last week](https://hackmd.io/Yv8mm14PQHyL4Id0itIesQ). The opcodes missing are for {...}CALL opcodes, `CALLDATACOPY` and `MCOPY`.
## Next week
Need to complete the integration with the statedb in Erigon. Hopefully, we will be able to create a proof of UniswapV2 swap next week with a real statedb.