-
Notifications
You must be signed in to change notification settings - Fork 4
Statediffing Geth code changes
This page describes the core changes to Geth to enable statediff subscriptions that we maintain in the https://github.com/makerdao/go-ethereum/ repository. Our changes are relatively minimal: a few hundred lines of code, plus tests and some configuration changes. These changes fall into the following categories:
- Changes to the state DB to return storage diffs.
- Changes to the blockchain to add a storage diff event feed.
- Changes that enable RPC subscriptions to the storage diff event feed.
- Cascading changes due to the modified state DB interface.
- Tests and configuration changes.
The central change in our fork is a modification to core/state/statedb.go
that returns an extra StateChanges
value from calls to statedb.Commit
. The state DB implementation is deep in the internals of Geth, and fortunately has not proven to change very frequently. The extra return value from statedb.Commit
cascades to other calls to this method in other areas of the codebase, but in most cases the value can be ignored.
Files:
-
core/state/statedb.go
: Calculate and return aStateChanges
map from calls toCommit
. -
core/state/stateobject.go
: Add adiffStorage
attribute to theStateObject
struct. -
core/state/statedb_test.go
: Additional tests for our changes, plus cascading changes from the change to thestatedb.Commit
return values.
We add an additional event.Feed
called stateChangeEventFeed
in core/blockchain.go
, similar to the existing event.Feed
entries for logs and blocks. In addition, we add a SubscribeStateChangeEvent
method to subscribe to state change events.
Files:
-
core/blockchain.go
: AddstateChangeEventFeed
-
core/blockchain.go
: Send state changes to feed followingCommit
. -
core/blockchain.go
: AddSubscribeStateChangeEvent
function. -
core/blockchain_test.go
: Add tests for above changes.
Adding an RPC subscription and filter query requires changing a number of files, but the pattern here is exactly the same implementation as filter queries for event logs: create a subscription, create a filter query, and expose these through the client interface.
Files:
-
core/events.go
: AddStateChangeEvent
. -
eth/api_backend.go
: AddSubscribeStateChangeEvent
to subscribe to state diff events. (Same pattern as log subscriptions). -
internal/ethapi/backend.go
: Register state change subscription. -
eth/filters/api.go
: Add a filter for state change subscriptions. Like logs, this accepts specific contract addresses to filter and maintains the same API as log filter queries. -
eth/filters/filter.go
: Register the statediff subscription. -
eth/filters/filter_system.go
: Add state change payloads to subscription struct, add handler for state change events. Update usage of subscription struct to include state change payloads. -
eth/filters/filter_system_test.go
: Add tests for state change subscriptions. -
eth/filters/statediff.go
: Add custom statediff filter. -
ethclient/ethclient.go
: Expose statediff subscription in client interface. -
light/lightchain.go
: Expose statediff subscription in client interface. -
les/api_backend.go
: Expose statediff subscription in client interface. -
accounts/abi/bind/backends/simulated.go
: Expose statediff subscription in client interface.
The updated state DB Commit
return value cascades to a few additional places in the codebase. In each of these, we ignore the additional arg. Here's an example.
Files:
cmd/evm/internal/t8ntool/execution.go
core/chain_makers.go
core/state/state_test.go
core/state/sync_test.go
eth/state_accessor.go
tests/state_test_util.go
- Add a Docker compose and github workflow to smoke test diff subscriptions
- Remove builders from
.travis.yml
(We don't need to build official images and cannot push them to the geth Docker hub) - Update a config parameter in
rpc/client_test.go