-
Notifications
You must be signed in to change notification settings - Fork 149
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
Atomic vm refactor #768
base: seperate-atomic-pkg-base
Are you sure you want to change the base?
Atomic vm refactor #768
Conversation
Co-authored-by: Quentin McGaw <quentin.mcgaw@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
Co-authored-by: Quentin McGaw <quentin.mcgaw@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
Co-authored-by: Quentin McGaw <quentin.mcgaw@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
Co-authored-by: Quentin McGaw <quentin.mcgaw@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
for chainID, requests := range requests { | ||
mergeAtomicOpsToMap(a.atomicOps, chainID, requests) | ||
} |
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.
this is a no-op since requests was nil
here: https://github.com/ava-labs/coreth/blob/seperate-atomic-pkg-base/plugin/evm/block.go#L186
blk := a.chain.GetBlockByNumber(height) | ||
if blk == nil { | ||
return nil, fmt.Errorf("block not found for height (%d)", height) | ||
} | ||
|
||
if !a.chain.HasState(blk.Root()) { | ||
return nil, fmt.Errorf("block root does not exist for height (%d), root (%s)", height, blk.Root()) | ||
} | ||
|
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.
moved to syncervm_server.go as this is a common check with state trie.
atomicTrie: atomicTrie, | ||
stateSyncRequestSize: stateSyncRequestSize, | ||
} | ||
func (a *AtomicSyncExtender) Initialize(backend AtomicBackend, atomicTrie AtomicTrie, stateSyncRequestSize uint16) { |
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.
This needs to be called after innervm initialize (so atomicbackend can be available)
type Visitor interface { | ||
ImportTx(*UnsignedImportTx) error | ||
ExportTx(*UnsignedExportTx) error | ||
} |
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.
This worked like a charm
atomicTrieDBPrefix = []byte("atomicTrieDB") | ||
atomicTrieMetaDBPrefix = []byte("atomicTrieMetaDB") | ||
appliedSharedMemoryCursorKey = []byte("atomicTrieLastAppliedToSharedMemory") |
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.
moved all these to repo as it seemed to me that it should be the one handling database operations.
@@ -165,13 +171,15 @@ func (client *stateSyncerClient) stateSync(ctx context.Context) error { | |||
return err | |||
} | |||
|
|||
// Sync the EVM trie and then the atomic trie. These steps could be done | |||
// in parallel or in the opposite order. Keeping them serial for simplicity for now. |
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.
hmmmm looks like it's actually simpler so we can run them in parallel now.
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.
definetly not in the current scope though
b, _ = cb58.Decode(key) | ||
pk, _ := secp256k1.ToPrivateKey(b) | ||
balance := new(big.Int).Mul(big.NewInt(params.Ether), big.NewInt(10)) | ||
g.Alloc[pk.EthAddress()] = types.GenesisAccount{Balance: balance} |
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.
test private keys are not init here yet. (we call this in a var block above)
*avalancheatomic.Memory, | ||
*enginetest.Sender, | ||
) { | ||
vm := WrapVM(&evm.VM{}) |
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.
we import evm.VM here (only here)
} | ||
|
||
// if the chainCtx.NetworkUpgrades is not empty, set the chain config | ||
// normally it should not be empty, but some tests may not set it | ||
if chainCtx.NetworkUpgrades != (upgrade.Config{}) { | ||
g.Config = params.GetChainConfig(chainCtx.NetworkUpgrades, new(big.Int).Set(chainID)) | ||
g.Config.NetworkUpgrades = params.GetNetworkUpgrades(chainCtx.NetworkUpgrades) |
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.
We should probably stop defaulting any part of genesis/chainConfig. This still modifies it but only the NetworkUpgrades.
we had few ugly cases in subnet-evm because we filled genesis/chainConfig and turned out that it was even more confusing to maintain.
} | ||
|
||
// initialize peer network | ||
if vm.p2pSender == 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.
seems this is unnecessary since we can directly pass appSender here.
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.
this was used in some testing, perhaps check with @joshua-kim
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.
It's not read anywhere in the repo, from what I can tell?
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.
even if this is being used anywhere, I think it was wrong.
@@ -185,93 +182,6 @@ func (utx *UnsignedImportTx) Burned(assetID ids.ID) (uint64, error) { | |||
return math.Sub(input, spent) | |||
} | |||
|
|||
// SemanticVerify this transaction is valid. | |||
func (utx *UnsignedImportTx) SemanticVerify( |
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.
moved to tx_semantic_verifier
@@ -178,75 +177,7 @@ func (utx *UnsignedExportTx) Burned(assetID ids.ID) (uint64, error) { | |||
return math.Sub(input, spent) | |||
} | |||
|
|||
// SemanticVerify this transaction is valid. | |||
func (utx *UnsignedExportTx) SemanticVerify( |
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.
moved to tx_semantic_verifier
vmerrs/vmerrs.go
Outdated
@@ -47,4 +47,7 @@ var ( | |||
ErrInvalidCode = errors.New("invalid code: must not begin with 0xef") | |||
ErrNonceUintOverflow = errors.New("nonce uint64 overflow") | |||
ErrAddrProhibited = errors.New("prohibited address cannot be sender or created contract address") | |||
ErrGenerateBlockFailed = errors.New("failed to generate block") |
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.
I'm trying to get rid of this package. Could we move this to a new package under plugin/evm so we don't mix ETH errors with avalanche vm errors?
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.
renamed this file to coreerrs (which IMO makes more sense) and moved this to plugin/evm/vmerrors
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.
I agree - very clear
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.
This change seems correct.
I think there is a lot of complexity in the initialize flow, which is a result of how we structured dependencies.
However, I think the tech debt of having two repositories is much greater than some added complexity to the VM initialization flow.
I will continue to look for some improvements but I think we should prioritize the repository merging then revisit cleaning up Initialize and improving the innerVM and wrapperVM abstractions.
In any case, in its current state, this would need a README.md that explains what's going on and which structs need to go through initialization prior to use and in which order.
plugin/evm/vm_extensible.go
Outdated
) | ||
|
||
/* | ||
// All these methods assumes that VM is already initialized |
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.
nit: I think we should move SetExtensionConfig above this comment.
Also not sure if you prefer the block comment /**/ here, seems we can just use //
} | ||
|
||
// initialize peer network | ||
if vm.p2pSender == 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.
this was used in some testing, perhaps check with @joshua-kim
plugin/evm/block.go
Outdated
_ = atomicState.Reject() // ignore this error so we can return the original error instead. | ||
} | ||
if b.extension != nil && (err != nil || !writes) { | ||
b.extension.OnError(b) |
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.
I know I originally requested to call this OnError, but it's also called on !writes
,
so perhaps a name like UnpinVerified()
or something else is better.
I think it might make sense to move the call to SemanticVerify
on extensions to this fn too (so all the extension calls are in a single place).
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.
I think unpinning is specific to atomic implementation. This should probably be called CleanupVerified
(since we actually cleanup everytime if !writes regarding of error)
type uninitializedHandler struct{} | ||
|
||
func (h *uninitializedHandler) OnLeafsRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, leafsRequest message.LeafsRequest) ([]byte, error) { | ||
return nil, errUninitialized |
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.
Would it be possible for this code path to be called? if so we shouldn't return an error since it would be fatal
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org> Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
…atomic-vm-refactor
Why this should be merged
This PR moves atomic logic to atomic pkg and adds atomic VM that wraps the evm/vm.
AvalancheGo PR: ava-labs/avalanchego#3702
How this works
Defines InnerVM/ExtensibleVM interfaces to extend and wrap plugin/vm with atomic logic and capabilities. Implement InnerVM/ExtensibleVM in evm/VM.
How this was tested
Need to be documented?
No
Need to update RELEASES.md?
updated