Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
4ee321d
move atomic state pkg
ceyonur May 14, 2025
d579ebf
specify intervals through configs
ceyonur May 14, 2025
3dfd923
Merge branch 'master' into atomic-state-pkg
ceyonur May 15, 2025
3e834ff
remove unnecessary vars
ceyonur May 15, 2025
92b3869
move to atomic sync pkg
ceyonur May 15, 2025
33007d2
commit unsaved file
ceyonur May 15, 2025
a6b320f
unexport bonus blocks
ceyonur May 15, 2025
e5eb9a6
unexport field
ceyonur May 15, 2025
aeceb84
convert initializes to news
ceyonur May 15, 2025
901cf35
fix linter
ceyonur May 15, 2025
5db77aa
Remove atomic trie from vm
ceyonur May 16, 2025
489a41a
Merge branch 'master' into atomic-state-pkg
ceyonur May 16, 2025
32e7934
update comment
ceyonur May 16, 2025
a4c593f
Merge branch 'atomic-state-pkg' into atomic-sync-pkg
ceyonur May 20, 2025
60c7462
Merge branch 'master' into atomic-sync-pkg
ceyonur May 22, 2025
a1fbd8b
fix licences
ceyonur May 22, 2025
531f2c8
reduce codec diffs with master
ceyonur May 22, 2025
b038108
unsaved changes
ceyonur May 23, 2025
60b3b98
fix struct name in strings
ceyonur May 23, 2025
dcf6ac0
Merge branch 'master' into atomic-sync-pkg
ceyonur May 23, 2025
55506bb
remove extra interface
ceyonur May 23, 2025
4cd9bd0
Merge branch 'atomic-sync-pkg' of github.com:ava-labs/coreth into ato…
ceyonur May 23, 2025
f6ed7ee
introduce atomic block extension
ceyonur May 23, 2025
1a9a959
rename block
ceyonur May 23, 2025
50e0136
add ID test
ceyonur May 23, 2025
aefbfc4
reviews
ceyonur May 23, 2025
bfee286
Merge branch 'atomic-sync-pkg' of github.com:ava-labs/coreth into ato…
ceyonur May 23, 2025
be02b5a
Merge branch 'master' into atomic-sync-pkg
ceyonur May 23, 2025
c1cea9c
implement atomicblockcontext
ceyonur May 23, 2025
038eec1
Merge branch 'atomic-sync-pkg' into atomic-block-extension
ceyonur May 23, 2025
c4b98df
remove params dep
ceyonur May 23, 2025
e24a62c
move block extender to vm
ceyonur May 26, 2025
2cd30cf
Merge branch 'master' into atomic-sync-pkg
ceyonur May 27, 2025
a1dcedb
Update plugin/evm/atomic/sync/atomic_leaf_handler.go
ceyonur May 27, 2025
c2c89b0
Update plugin/evm/atomic/sync/atomic_sync_extender.go
ceyonur May 27, 2025
060ca22
Update plugin/evm/atomic/sync/atomic_sync_extender.go
ceyonur May 27, 2025
8c84949
remove reduntant methods
ceyonur May 27, 2025
cc609ab
Merge branch 'master' into atomic-sync-pkg
ceyonur May 27, 2025
2ddb618
Merge branch 'atomic-sync-pkg' into atomic-block-extension
ceyonur May 27, 2025
2ab706a
Merge branch 'atomic-block-extension' into atomic-vm-block-extender
ceyonur May 27, 2025
f35754e
Merge branch 'master' into atomic-vm-block-extender
ceyonur Jun 5, 2025
f9d33bd
revert merge changes
ceyonur Jun 5, 2025
a96e1c9
revert extra changes
ceyonur Jun 5, 2025
6aa0d98
Reviews
ceyonur Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package vm

import (
"errors"
Expand Down Expand Up @@ -29,7 +29,8 @@ var (

var (
errNilEthBlock = errors.New("nil ethBlock")
errMissingUTXOs = errors.New("missing UTXOs")
ErrMissingUTXOs = errors.New("missing UTXOs")
ErrEmptyBlock = errors.New("empty block")
)

type blockExtender struct {
Expand Down Expand Up @@ -131,7 +132,7 @@ func (be *blockExtension) SyntacticVerify(rules extras.Rules) error {
txs := ethBlock.Transactions()
atomicTxs := be.atomicTxs
if len(txs) == 0 && len(atomicTxs) == 0 {
return errEmptyBlock
return ErrEmptyBlock
}

// If we are in ApricotPhase4, ensure that ExtDataGasUsed is populated correctly.
Expand Down Expand Up @@ -193,12 +194,12 @@ func (be *blockExtension) Accept(acceptedBatch database.Batch) error {
vm := be.blockExtender.vm
for _, tx := range be.atomicTxs {
// Remove the accepted transaction from the mempool
vm.mempool.RemoveTx(tx)
vm.AtomicMempool().RemoveTx(tx)
}

// Update VM state for atomic txs in this block. This includes updating the
// atomic tx repo, atomic trie, and shared memory.
atomicState, err := vm.atomicBackend.GetVerifiedAtomicState(common.Hash(be.block.ID()))
atomicState, err := vm.AtomicBackend().GetVerifiedAtomicState(common.Hash(be.block.ID()))
if err != nil {
// should never occur since [b] must be verified before calling Accept
return err
Expand All @@ -213,12 +214,12 @@ func (be *blockExtension) Reject() error {
vm := be.blockExtender.vm
for _, tx := range be.atomicTxs {
// Re-issue the transaction in the mempool, continue even if it fails
vm.mempool.RemoveTx(tx)
if err := vm.mempool.AddRemoteTx(tx); err != nil {
vm.AtomicMempool().RemoveTx(tx)
if err := vm.AtomicMempool().AddRemoteTx(tx); err != nil {
log.Debug("Failed to re-issue transaction in rejected block", "txID", tx.ID(), "err", err)
}
}
atomicState, err := vm.atomicBackend.GetVerifiedAtomicState(common.Hash(be.block.ID()))
atomicState, err := vm.AtomicBackend().GetVerifiedAtomicState(common.Hash(be.block.ID()))
if err != nil {
// should never occur since [b] must be verified before calling Reject
return err
Expand All @@ -229,9 +230,7 @@ func (be *blockExtension) Reject() error {
// CleanupVerified is called when the block is cleaned up after a failed insertion.
func (be *blockExtension) CleanupVerified() {
vm := be.blockExtender.vm
// If an error occurred inserting the block into the chain or if we are not pinning to memory,
// unpin the atomic trie changes from memory (if they were pinned).
if atomicState, err := vm.atomicBackend.GetVerifiedAtomicState(be.block.GetEthBlock().Hash()); err == nil {
if atomicState, err := vm.AtomicBackend().GetVerifiedAtomicState(be.block.GetEthBlock().Hash()); err == nil {
atomicState.Reject()
}
}
Expand All @@ -247,7 +246,7 @@ func (be *blockExtension) verifyUTXOsPresent(atomicTxs []*atomic.Tx) error {
b := be.block
blockHash := common.Hash(b.ID())
vm := be.blockExtender.vm
if vm.atomicBackend.IsBonus(b.Height(), blockHash) {
if vm.AtomicBackend().IsBonus(b.Height(), blockHash) {
log.Info("skipping atomic tx verification on bonus block", "block", blockHash)
return nil
}
Expand All @@ -260,7 +259,7 @@ func (be *blockExtension) verifyUTXOsPresent(atomicTxs []*atomic.Tx) error {
return err
}
if _, err := vm.ctx.SharedMemory.Get(chainID, requests.RemoveRequests); err != nil {
return fmt.Errorf("%w: %s", errMissingUTXOs, err)
return fmt.Errorf("%w: %s", ErrMissingUTXOs, err)
}
}
return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package vm

import (
_ "embed"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package atomic
package vm

import (
"context"
Expand All @@ -17,11 +17,12 @@ import (
"github.com/ava-labs/avalanchego/vms/platformvm/fx"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/plugin/evm/atomic"
"github.com/ava-labs/coreth/plugin/evm/extension"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap0"
)

var _ Visitor = (*SemanticVerifier)(nil)
var _ atomic.Visitor = (*SemanticVerifier)(nil)

var (
ErrAssetIDMismatch = errors.New("asset IDs in the input don't match the utxo")
Expand Down Expand Up @@ -49,13 +50,13 @@ type VerifierBackend struct {
// SemanticVerifier is a visitor that checks the semantic validity of atomic transactions.
type SemanticVerifier struct {
Backend *VerifierBackend
Tx *Tx
Tx *atomic.Tx
Parent extension.ExtendedBlock
BaseFee *big.Int
}

// ImportTx verifies this transaction is valid.
func (s *SemanticVerifier) ImportTx(utx *UnsignedImportTx) error {
func (s *SemanticVerifier) ImportTx(utx *atomic.UnsignedImportTx) error {
backend := s.Backend
ctx := backend.Ctx
rules := backend.Rules
Expand All @@ -73,7 +74,7 @@ func (s *SemanticVerifier) ImportTx(utx *UnsignedImportTx) error {
if err != nil {
return err
}
txFee, err := CalculateDynamicFee(gasUsed, s.BaseFee)
txFee, err := atomic.CalculateDynamicFee(gasUsed, s.BaseFee)
if err != nil {
return err
}
Expand Down Expand Up @@ -118,7 +119,7 @@ func (s *SemanticVerifier) ImportTx(utx *UnsignedImportTx) error {
utxoBytes := allUTXOBytes[i]

utxo := &avax.UTXO{}
if _, err := Codec.Unmarshal(utxoBytes, utxo); err != nil {
if _, err := atomic.Codec.Unmarshal(utxoBytes, utxo); err != nil {
return fmt.Errorf("failed to unmarshal UTXO: %w", err)
}

Expand Down Expand Up @@ -148,7 +149,7 @@ func conflicts(backend *VerifierBackend, inputs set.Set[ids.ID], ancestor extens
lastAcceptedHeight := lastAcceptedBlock.Height()
for ancestor.Height() > lastAcceptedHeight {
ancestorExtIntf := ancestor.GetBlockExtension()
ancestorExt, ok := ancestorExtIntf.(AtomicBlockContext)
ancestorExt, ok := ancestorExtIntf.(atomic.AtomicBlockContext)
if !ok {
return fmt.Errorf("expected block extension to be AtomicBlockContext but got %T", ancestorExtIntf)
}
Expand Down Expand Up @@ -180,7 +181,7 @@ func conflicts(backend *VerifierBackend, inputs set.Set[ids.ID], ancestor extens
}

// ExportTx verifies this transaction is valid.
func (s *SemanticVerifier) ExportTx(utx *UnsignedExportTx) error {
func (s *SemanticVerifier) ExportTx(utx *atomic.UnsignedExportTx) error {
backend := s.Backend
ctx := backend.Ctx
rules := backend.Rules
Expand All @@ -198,7 +199,7 @@ func (s *SemanticVerifier) ExportTx(utx *UnsignedExportTx) error {
if err != nil {
return err
}
txFee, err := CalculateDynamicFee(gasUsed, s.BaseFee)
txFee, err := atomic.CalculateDynamicFee(gasUsed, s.BaseFee)
if err != nil {
return err
}
Expand Down
111 changes: 111 additions & 0 deletions plugin/evm/atomic/vm/vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package vm

import (
"context"
"fmt"

avalanchedatabase "github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/snow"
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/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/txpool"
"github.com/ava-labs/coreth/plugin/evm/extension"

"github.com/ava-labs/libevm/common"
)

var (
_ block.ChainVM = (*VM)(nil)
_ block.BuildBlockWithContextChainVM = (*VM)(nil)
_ block.StateSyncableVM = (*VM)(nil)
)

// TODO: remove this
// InnerVM is the interface that must be implemented by the VM
// that's being wrapped by the extension
type InnerVM interface {
extension.ExtensibleVM
avalanchecommon.VM
block.ChainVM
block.BuildBlockWithContextChainVM
block.StateSyncableVM

// TODO: remove these
AtomicBackend() *state.AtomicBackend
AtomicMempool() *txpool.Mempool
}

type VM struct {
InnerVM
ctx *snow.Context
}

func WrapVM(vm InnerVM) *VM {
return &VM{InnerVM: vm}
}

// Initialize implements the snowman.ChainVM interface
func (vm *VM) Initialize(
ctx context.Context,
chainCtx *snow.Context,
db avalanchedatabase.Database,
genesisBytes []byte,
upgradeBytes []byte,
configBytes []byte,
toEngine chan<- avalanchecommon.Message,
fxs []*avalanchecommon.Fx,
appSender avalanchecommon.AppSender,
) error {
vm.ctx = chainCtx

var extDataHashes map[common.Hash]common.Hash
// Set the chain config for mainnet/fuji chain IDs
switch chainCtx.NetworkID {
case constants.MainnetID:
extDataHashes = mainnetExtDataHashes
case constants.FujiID:
extDataHashes = fujiExtDataHashes
}
// Free the memory of the extDataHash map
fujiExtDataHashes = nil
mainnetExtDataHashes = nil

// Create the atomic extension structs
// some of them need to be initialized after the inner VM is initialized
blockExtender := newBlockExtender(extDataHashes, vm)

extensionConfig := &extension.Config{
BlockExtender: blockExtender,
}
if err := vm.SetExtensionConfig(extensionConfig); err != nil {
return fmt.Errorf("failed to set extension config: %w", err)
}

// Initialize inner vm with the provided parameters
if err := vm.InnerVM.Initialize(
ctx,
chainCtx,
db,
genesisBytes,
upgradeBytes,
configBytes,
toEngine,
fxs,
appSender,
); err != nil {
return fmt.Errorf("failed to initialize inner VM: %w", err)
}
return nil
}

func (vm *VM) chainConfigExtra() *extras.ChainConfig {
return params.GetExtra(vm.Ethereum().BlockChain().Config())
}
13 changes: 7 additions & 6 deletions plugin/evm/export_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/plugin/evm/atomic"
atomicvm "github.com/ava-labs/coreth/plugin/evm/atomic/vm"
"github.com/ava-labs/coreth/utils"
"github.com/ava-labs/libevm/common"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -922,7 +923,7 @@ func TestExportTxSemanticVerify(t *testing.T) {
t.Fatal(err)
}

backend := &atomic.VerifierBackend{
backend := &atomicvm.VerifierBackend{
Ctx: vm.ctx,
Fx: &vm.fx,
Rules: test.rules,
Expand All @@ -935,7 +936,7 @@ func TestExportTxSemanticVerify(t *testing.T) {
tx := test.tx
exportTx := tx.UnsignedAtomicTx

err := exportTx.Visit(&atomic.SemanticVerifier{
err := exportTx.Visit(&atomicvm.SemanticVerifier{
Backend: backend,
Tx: tx,
Parent: parent,
Expand Down Expand Up @@ -1783,7 +1784,7 @@ func TestNewExportTx(t *testing.T) {

exportTx := tx.UnsignedAtomicTx

backend := &atomic.VerifierBackend{
backend := &atomicvm.VerifierBackend{
Ctx: tvm.vm.ctx,
Fx: &tvm.vm.fx,
Rules: tvm.vm.currentRules(),
Expand All @@ -1792,7 +1793,7 @@ func TestNewExportTx(t *testing.T) {
SecpCache: tvm.vm.secpCache,
}

if err := exportTx.Visit(&atomic.SemanticVerifier{
if err := exportTx.Visit(&atomicvm.SemanticVerifier{
Backend: backend,
Tx: tx,
Parent: parent,
Expand Down Expand Up @@ -1987,7 +1988,7 @@ func TestNewExportTxMulticoin(t *testing.T) {
}

exportTx := tx.UnsignedAtomicTx
backend := &atomic.VerifierBackend{
backend := &atomicvm.VerifierBackend{
Ctx: tvm.vm.ctx,
Fx: &tvm.vm.fx,
Rules: tvm.vm.currentRules(),
Expand All @@ -1996,7 +1997,7 @@ func TestNewExportTxMulticoin(t *testing.T) {
SecpCache: tvm.vm.secpCache,
}

if err := exportTx.Visit(&atomic.SemanticVerifier{
if err := exportTx.Visit(&atomicvm.SemanticVerifier{
Backend: backend,
Tx: tx,
Parent: parent,
Expand Down
Loading