-
Notifications
You must be signed in to change notification settings - Fork 159
move syncers to atomic vm #1009
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,12 +25,14 @@ type extender struct { | |
| } | ||
|
|
||
| // Initialize initializes the sync extender with the backend and trie. | ||
| func NewExtender(backend *state.AtomicBackend, trie *state.AtomicTrie, requestSize uint16) *extender { | ||
| return &extender{ | ||
| backend: backend, | ||
| trie: trie, | ||
| requestSize: requestSize, | ||
| } | ||
| func NewExtender() *extender { | ||
| return &extender{} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning non-exported types can cause problems at the call sites as they're really only useable as interfaces, but because they're not exported there's no way to check the documentation to see if they implement the interface of interest. |
||
| } | ||
|
|
||
| func (a *extender) Initialize(backend *state.AtomicBackend, trie *state.AtomicTrie, requestSize uint16) { | ||
| a.backend = backend | ||
| a.trie = trie | ||
| a.requestSize = requestSize | ||
|
Comment on lines
+33
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a constructor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact yes, but we need to initialize this after calling the |
||
| } | ||
|
|
||
| func (a *extender) Sync(ctx context.Context, client syncclient.LeafClient, verDB *versiondb.Database, summary message.Syncable) error { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,23 +4,45 @@ | |
| package sync | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
|
|
||
| "github.com/ava-labs/avalanchego/codec" | ||
| "github.com/ava-labs/avalanchego/ids" | ||
| "github.com/ava-labs/coreth/plugin/evm/message" | ||
| "github.com/ava-labs/coreth/sync/handlers" | ||
| "github.com/ava-labs/coreth/sync/handlers/stats" | ||
|
|
||
| "github.com/ava-labs/libevm/metrics" | ||
| "github.com/ava-labs/libevm/triedb" | ||
| ) | ||
|
|
||
| // leafHandler is a wrapper around handlers.LeafRequestHandler that allows for initialization after creation | ||
| var ( | ||
| _ handlers.LeafRequestHandler = (*uninitializedHandler)(nil) | ||
|
|
||
| errUninitialized = errors.New("uninitialized handler") | ||
| ) | ||
|
|
||
| type uninitializedHandler struct{} | ||
|
|
||
| func (h *uninitializedHandler) OnLeafsRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, leafsRequest message.LeafsRequest) ([]byte, error) { | ||
| return nil, errUninitialized | ||
| } | ||
|
|
||
| // atomicLeafHandler is a wrapper around handlers.LeafRequestHandler that allows for initialization after creation | ||
| type leafHandler struct { | ||
| handlers.LeafRequestHandler | ||
| } | ||
|
|
||
| // Initialize initializes the leafHandler with the provided atomicTrieDB, trieKeyLength, and networkCodec | ||
| func NewLeafHandler(atomicTrieDB *triedb.Database, trieKeyLength int, networkCodec codec.Manager) *leafHandler { | ||
| handlerStats := stats.GetOrRegisterHandlerStats(metrics.Enabled) | ||
| // NewAtomicLeafHandler returns a new uninitialzied atomicLeafHandler that can be later initialized | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It can't be. It always returns EDIT: looking at the code below, I think you mean "can be later replaced". |
||
| func NewLeafHandler() *leafHandler { | ||
| return &leafHandler{ | ||
| LeafRequestHandler: handlers.NewLeafsRequestHandler(atomicTrieDB, trieKeyLength, nil, networkCodec, handlerStats), | ||
| LeafRequestHandler: &uninitializedHandler{}, | ||
| } | ||
| } | ||
|
|
||
| // Initialize initializes the atomicLeafHandler with the provided atomicTrieDB, trieKeyLength, and networkCodec | ||
| func (a *leafHandler) Initialize(atomicTrieDB *triedb.Database, trieKeyLength int, networkCodec codec.Manager) { | ||
| handlerStats := stats.GetOrRegisterHandlerStats(metrics.Enabled) | ||
| a.LeafRequestHandler = handlers.NewLeafsRequestHandler(atomicTrieDB, trieKeyLength, nil, networkCodec, handlerStats) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,10 +20,12 @@ type summaryProvider struct { | |
| trie *state.AtomicTrie | ||
| } | ||
|
|
||
| func NewSummaryProvider(atomicTrie *state.AtomicTrie) *summaryProvider { | ||
| return &summaryProvider{ | ||
| trie: atomicTrie, | ||
| } | ||
| func NewSummaryProvider() *summaryProvider { | ||
| return &summaryProvider{} | ||
| } | ||
|
|
||
| func (a *summaryProvider) Initialize(trie *state.AtomicTrie) { | ||
| a.trie = trie | ||
|
Comment on lines
+23
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All my comments on |
||
| } | ||
|
|
||
| // StateSummaryAtBlock returns the block state summary at [blk] if valid. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,12 +12,15 @@ import ( | |
| avalanchecommon "github.com/ava-labs/avalanchego/snow/engine/common" | ||
| "github.com/ava-labs/avalanchego/snow/engine/snowman/block" | ||
| "github.com/ava-labs/avalanchego/utils/constants" | ||
| "github.com/ava-labs/avalanchego/utils/timer/mockable" | ||
|
|
||
| "github.com/ava-labs/coreth/params" | ||
| "github.com/ava-labs/coreth/params/extras" | ||
| "github.com/ava-labs/coreth/plugin/evm/atomic/state" | ||
| "github.com/ava-labs/coreth/plugin/evm/atomic/sync" | ||
| "github.com/ava-labs/coreth/plugin/evm/atomic/txpool" | ||
| "github.com/ava-labs/coreth/plugin/evm/extension" | ||
| "github.com/ava-labs/coreth/plugin/evm/message" | ||
|
|
||
| "github.com/ava-labs/libevm/common" | ||
| ) | ||
|
|
@@ -46,6 +49,8 @@ type InnerVM interface { | |
| type VM struct { | ||
| InnerVM | ||
| ctx *snow.Context | ||
|
|
||
| clock mockable.Clock | ||
| } | ||
|
|
||
| func WrapVM(vm InnerVM) *VM { | ||
|
|
@@ -81,9 +86,24 @@ func (vm *VM) Initialize( | |
| // Create the atomic extension structs | ||
| // some of them need to be initialized after the inner VM is initialized | ||
| blockExtender := newBlockExtender(extDataHashes, vm) | ||
| syncExtender := sync.NewExtender() | ||
| syncProvider := sync.NewSummaryProvider() | ||
| // Create and pass the leaf handler to the atomic extension | ||
| // it will be initialized after the inner VM is initialized | ||
| leafHandler := sync.NewLeafHandler() | ||
| atomicLeafTypeConfig := &extension.LeafRequestConfig{ | ||
| LeafType: sync.TrieNode, | ||
| MetricName: "sync_atomic_trie_leaves", | ||
| Handler: leafHandler, | ||
| } | ||
|
|
||
| extensionConfig := &extension.Config{ | ||
| BlockExtender: blockExtender, | ||
| BlockExtender: blockExtender, | ||
| SyncableParser: sync.NewSummaryParser(), | ||
| SyncExtender: syncExtender, | ||
| SyncSummaryProvider: syncProvider, | ||
| ExtraSyncLeafHandlerConfig: atomicLeafTypeConfig, | ||
| Clock: &vm.clock, | ||
| } | ||
| if err := vm.SetExtensionConfig(extensionConfig); err != nil { | ||
| return fmt.Errorf("failed to set extension config: %w", err) | ||
|
|
@@ -103,6 +123,12 @@ func (vm *VM) Initialize( | |
| ); err != nil { | ||
| return fmt.Errorf("failed to initialize inner VM: %w", err) | ||
| } | ||
|
|
||
| // Atomic backend is available now, we can initialize structs that depend on it | ||
| syncProvider.Initialize(vm.AtomicBackend().AtomicTrie()) | ||
| syncExtender.Initialize(vm.AtomicBackend(), vm.AtomicBackend().AtomicTrie(), vm.Config().StateSyncRequestSize) | ||
| leafHandler.Initialize(vm.AtomicBackend().AtomicTrie().TrieDB(), state.TrieKeyLength, message.Codec) | ||
|
|
||
|
Comment on lines
+128
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is confusing because of the embedded atomicBE := vm.InnerVM.AtomicBackend()
atomicTrie := atomicBE.AtomicTrie()
syncProvider.Initialize(atomicTrie)
syncExtender.Initialize(atomicBE, atomicTrie, vm.Config().StateSyncRequestSize)
leafHandler.Initialize(atomicTrie.TrieDB(), state.TrieKeyLength, message.Codec)I appreciate that this is a means to an end, but I'm still really concerned about this pattern. The PR chain needs to eventually simplify construction and initialisation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In one of the previous PRs it was suggested to call InnerVM methods implicitly to reduce the complexity, but I agree it's easier to figure them out if they were explicit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the other hand atomicBackend will be moved to atomic/VM in #1011 |
||
| return nil | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there a constructor if it doesn't do anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bc it was using an unexported struct