mirror of
https://github.com/luxfi/coreth.git
synced 2026-10-30 17:00:51 +00:00
85 lines
2.7 KiB
Go
85 lines
2.7 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package state
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/luxfi/coreth/plugin/evm/atomic"
|
|
|
|
"github.com/luxfi/database"
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/luxfi/ids"
|
|
log "github.com/luxfi/log"
|
|
luxatomic "github.com/luxfi/vm/chains/atomic"
|
|
)
|
|
|
|
// atomicState implements the AtomicState interface using
|
|
// a pointer to the atomicBackend.
|
|
type atomicState struct {
|
|
backend *AtomicBackend
|
|
blockHash common.Hash
|
|
blockHeight uint64
|
|
txs []*atomic.Tx
|
|
atomicOps map[ids.ID]*luxatomic.Requests
|
|
atomicRoot common.Hash
|
|
}
|
|
|
|
func (a *atomicState) Root() common.Hash {
|
|
return a.atomicRoot
|
|
}
|
|
|
|
// Accept writes the atomic operations to the database and
|
|
// updates the last accepted block in the atomic backend.
|
|
// It also commits the `commitBatch` to the shared memory.
|
|
func (a *atomicState) Accept(commitBatch database.Batch) error {
|
|
isBonus := a.backend.IsBonus(a.blockHeight, a.blockHash)
|
|
// Update the atomic tx repository. Note it is necessary to invoke
|
|
// the correct method taking bonus blocks into consideration.
|
|
if isBonus {
|
|
if err := a.backend.repo.WriteBonus(a.blockHeight, a.txs); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if err := a.backend.repo.Write(a.blockHeight, a.txs); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Accept the root of this atomic trie (will be persisted if at a commit interval)
|
|
if _, err := a.backend.atomicTrie.AcceptTrie(a.blockHeight, a.atomicRoot); err != nil {
|
|
return err
|
|
}
|
|
// Update the last accepted block to this block and remove it from
|
|
// the map tracking undecided blocks.
|
|
a.backend.lastAcceptedHash = a.blockHash
|
|
delete(a.backend.verifiedRoots, a.blockHash)
|
|
|
|
// get changes from the atomic trie and repository in a batch
|
|
// to be committed atomically with [commitBatch] and shared memory.
|
|
atomicChangesBatch, err := a.backend.repo.db.CommitBatch()
|
|
if err != nil {
|
|
return fmt.Errorf("could not create commit batch in atomicState accept: %w", err)
|
|
}
|
|
|
|
// If this is a bonus block, write [commitBatch] without applying atomic ops
|
|
// to shared memory.
|
|
if isBonus {
|
|
log.Info("skipping atomic tx acceptance on bonus block", "block", a.blockHash)
|
|
return luxatomic.WriteAll(commitBatch, atomicChangesBatch)
|
|
}
|
|
|
|
// Otherwise, atomically commit pending changes in the version db with
|
|
// atomic ops to shared memory.
|
|
return a.backend.sharedMemory.Apply(a.atomicOps, commitBatch, atomicChangesBatch)
|
|
}
|
|
|
|
// Reject frees memory associated with the state change.
|
|
func (a *atomicState) Reject() error {
|
|
// Remove the block from the map of undecided blocks.
|
|
delete(a.backend.verifiedRoots, a.blockHash)
|
|
// Unpin the rejected atomic trie root from memory.
|
|
return a.backend.atomicTrie.RejectTrie(a.atomicRoot)
|
|
}
|