Skip to content
This repository has been archived by the owner on Jun 9, 2024. It is now read-only.

fix(journal): Restructure journals #1135

Merged
merged 6 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions cosmos/x/evm/plugins/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import (

// Base is the base interface which all x/evm Polaris plugins must implement

type Base interface {
IsPlugin()
}
type Base interface{}

// HasGenesis represents the base class that all x/evm Polaris plugins which have
// InitGenesis or ExportGenesis methods must implement
Expand Down
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/block/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,3 @@ func (p *plugin) GetNewBlockMetadata(number uint64) (common.Address, uint64) {
}
return common.BytesToAddress(valBz), uint64(cometHeader.Time.UTC().Unix())
}

func (p *plugin) IsPlugin() {}
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/configuration/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,3 @@ func (p *plugin) FeeCollector() *common.Address {
addr := common.BytesToAddress([]byte(authtypes.FeeCollectorName))
return &addr
}

func (p *plugin) IsPlugin() {}
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/gas/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,3 @@ func (p *plugin) resetMeters(ctx sdk.Context) {
p.consensusMaxGas = uint64(block.MaxGas)
}
}

func (p *plugin) IsPlugin() {}
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/historical/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,3 @@ func NewPlugin(
func (p *plugin) Prepare(ctx context.Context) {
p.ctx = sdk.UnwrapSDKContext(ctx)
}

func (p *plugin) IsPlugin() {}
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/precompile/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,3 @@ func (p *plugin) disableReentrancy(sdb vm.PolarisStateDB) {
// restore ctx gas configs for continuing precompile execution
p.sp.SetGasConfig(p.kvGasConfig, p.transientKVGasConfig)
}

func (p *plugin) IsPlugin() {}
1 change: 0 additions & 1 deletion cosmos/x/evm/plugins/state/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,4 +546,3 @@ func (p *plugin) SetGasConfig(kvGasConfig, transientKVGasConfig storetypes.GasCo
}

// IsPlugin implements plugins.Base.
func (p *plugin) IsPlugin() {}
2 changes: 0 additions & 2 deletions cosmos/x/evm/plugins/txpool/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,3 @@ func (p *plugin) SendPrivTx(signedTx *coretypes.Transaction) error {
// the tx.
return p.EthTxPool.Insert(sdk.Context{}.WithPriority(signedTx.GasPrice().Int64()), cosmosTx)
}

func (p *plugin) IsPlugin() {}
44 changes: 17 additions & 27 deletions eth/core/state/journal/access_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ package journal

import (
"pkg.berachain.dev/polaris/eth/common"
"pkg.berachain.dev/polaris/lib/ds"
"pkg.berachain.dev/polaris/lib/ds/stack"
libtypes "pkg.berachain.dev/polaris/lib/types"
"pkg.berachain.dev/polaris/lib/utils"
)
Expand All @@ -43,18 +41,17 @@ type Accesslist interface {
AddressInAccessList(common.Address) bool
}

// accessList is a `baseJournal` that tracks the access list.
type accessList struct {
*AccessList // current access list, always the head of journal stack.
journal ds.Stack[*AccessList] // journal of access lists.
baseJournal[*AccessList] // journal of access lists.
}

// NewAccesslist returns a new `accessList` journal.
func NewAccesslist() Accesslist {
journal := stack.New[*AccessList](initCapacity)
journal := newBaseJournal[*AccessList](initCapacity)
journal.Push(NewAccessList())
return &accessList{
AccessList: journal.Peek(),
journal: journal,
baseJournal: journal,
}
}

Expand All @@ -65,35 +62,31 @@ func (al *accessList) RegistryKey() string {

// AddAddressToAccessList implements `state.AccessListJournal`.
func (al *accessList) AddAddressToAccessList(addr common.Address) {
al.AddAddress(addr)
al.Peek().AddAddress(addr)
}

// AddSlotToAccessList implements `state.AccessListJournal`.
func (al *accessList) AddSlotToAccessList(addr common.Address, slot common.Hash) {
al.AddSlot(addr, slot)
al.Peek().AddSlot(addr, slot)
}

// AddressInAccessList implements `state.AccessListJournal`.
func (al *accessList) AddressInAccessList(addr common.Address) bool {
return al.ContainsAddress(addr)
return al.Peek().ContainsAddress(addr)
}

// SlotInAccessList implements `state.AccessListJournal`.
func (al *accessList) SlotInAccessList(addr common.Address, slot common.Hash) (bool, bool) {
return al.Contains(addr, slot)
return al.Peek().Contains(addr, slot)
}

// `Snapshot` implements `libtypes.Snapshottable`.
// Snapshot implements `libtypes.Snapshottable`.
func (al *accessList) Snapshot() int {
al.AccessList = al.AccessList.Copy()
al.journal.Push(al.AccessList)
return al.journal.Size() - 1
}

// RevertToSnapshot implements `libtypes.Snapshottable`.
func (al *accessList) RevertToSnapshot(id int) {
al.journal.PopToSize(id)
al.AccessList = al.journal.Peek()
al.Push(al.Peek().Copy())
// Accesslist is size minus one, since we want to revert to the place in the stack
// where snapshot was called, which since we need to push a copy on the stack, is
// the size minus one.
return al.baseJournal.Size() - 1
}

// Finalize implements `libtypes.Controllable`.
Expand All @@ -103,15 +96,12 @@ func (al *accessList) Finalize() {

// Clone implements `libtypes.Cloneable`.
func (al *accessList) Clone() Accesslist {
size := al.journal.Size()
cpy := &accessList{
AccessList: al.AccessList.Copy(),
journal: stack.New[*AccessList](size),
baseJournal: newBaseJournal[*AccessList](al.Capacity()),
}

cpy.journal.Push(cpy.AccessList)
for i := 1; i < size; i++ { // skip the root, already pushed above
cpy.journal.Push(al.journal.PeekAt(i).Copy())
for i := 0; i < al.Size(); i++ { // skip the root, already pushed above
cpy.Push(al.PeekAt(i).Copy())
}

return cpy
Expand Down
48 changes: 18 additions & 30 deletions eth/core/state/journal/access_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,49 +46,37 @@ var _ = Describe("AccessList", func() {
})

It("should support controllable access list operations", func() {
Expect(al.AddAddress(a1)).To(BeTrue())
Expect(al.ContainsAddress(a1)).To(BeTrue())
Expect(al.ContainsAddress(a2)).To(BeFalse())
al.DeleteAddress(a1)
Expect(al.ContainsAddress(a1)).To(BeFalse())
al.AddAddressToAccessList(a1)
Expect(al.AddressInAccessList(a1)).To(BeTrue())
Expect(al.AddressInAccessList(a2)).To(BeFalse())
al.Peek().DeleteAddress(a1)
Expect(al.AddressInAccessList(a1)).To(BeFalse())

ac, sc := al.AddSlot(a1, s1)
Expect(ac).To(BeTrue())
Expect(sc).To(BeTrue())
ac, sc = al.AddSlot(a1, s2)
Expect(ac).To(BeFalse())
Expect(sc).To(BeTrue())
al.AddSlotToAccessList(a1, s1)
al.AddSlotToAccessList(a1, s2)

id := al.Snapshot()
al.AddSlotToAccessList(a2, s1)

ac, sc = al.AddSlot(a2, s1)
Expect(ac).To(BeTrue())
Expect(sc).To(BeTrue())
Expect(al.ContainsAddress(a2)).To(BeTrue())
Expect(al.AddressInAccessList(a2)).To(BeTrue())

al.RevertToSnapshot(id)
Expect(al.ContainsAddress(a2)).To(BeFalse())
Expect(al.AddressInAccessList(a2)).To(BeFalse())

Expect(func() { al.Finalize() }).ToNot(Panic())
Expect(al.journal.Size()).To(Equal(1))
Expect(al.Size()).To(Equal(1))
})

It("should clone correctly", func() {
ac, sc := al.AddSlot(a1, s1)
Expect(ac).To(BeTrue())
Expect(sc).To(BeTrue())
ac, sc = al.AddSlot(a1, s2)
Expect(ac).To(BeFalse())
Expect(sc).To(BeTrue())
al.AddSlotToAccessList(a1, s1)
al.AddSlotToAccessList(a1, s2)

al2 := utils.MustGetAs[*accessList](al.Clone())
Expect(al2.ContainsAddress(a1)).To(BeTrue())
Expect(al2.ContainsAddress(a2)).To(BeFalse())
Expect(al2.AddressInAccessList(a1)).To(BeTrue())
Expect(al2.AddressInAccessList(a2)).To(BeFalse())

ac, sc = al2.AddSlot(a2, s1)
Expect(ac).To(BeTrue())
Expect(sc).To(BeTrue())
Expect(al2.ContainsAddress(a2)).To(BeTrue())
Expect(al.ContainsAddress(a2)).To(BeFalse())
al2.AddSlotToAccessList(a2, s1)
Expect(al2.AddressInAccessList(a2)).To(BeTrue())
Expect(al.AddressInAccessList(a2)).To(BeFalse())
})
})
52 changes: 52 additions & 0 deletions eth/core/state/journal/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: BUSL-1.1
//
// Copyright (C) 2023, Berachain Foundation. All rights reserved.
// Use of this software is govered by the Business Source License included
// in the LICENSE file of this repository and at www.mariadb.com/bsl11.
//
// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY
// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER
// VERSIONS OF THE LICENSED WORK.
//
// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF
// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF
// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).
//
// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
// TITLE.

package journal

import (
"pkg.berachain.dev/polaris/lib/ds"
"pkg.berachain.dev/polaris/lib/ds/stack"
)

// baseJournal is a struct that holds a stack of items.
type baseJournal[T any] struct {
ds.Stack[T]
}

// newBaseJournal returns a new `baseJournal` with the given initial capacity.
func newBaseJournal[T any](initialCapacity int) baseJournal[T] {
return baseJournal[T]{
Stack: stack.New[T](initialCapacity),
}
}

// Snapshot takes a snapshot of the `Logs` store.
//
// Snapshot implements `libtypes.Snapshottable`.
func (j *baseJournal[T]) Snapshot() int {
return j.Size()
}

// RevertToSnapshot reverts the `Logs` store to a given snapshot id.
//
// RevertToSnapshot implements `libtypes.Snapshottable`.
func (j *baseJournal[T]) RevertToSnapshot(id int) {
j.PopToSize(id)
}
46 changes: 14 additions & 32 deletions eth/core/state/journal/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ package journal
import (
"pkg.berachain.dev/polaris/eth/common"
coretypes "pkg.berachain.dev/polaris/eth/core/types"
"pkg.berachain.dev/polaris/lib/ds"
"pkg.berachain.dev/polaris/lib/ds/stack"
libtypes "pkg.berachain.dev/polaris/lib/types"
)

Expand All @@ -48,15 +46,15 @@ type Log interface {

// logs is a state plugin that tracks Ethereum logs.
type logs struct {
journal ds.Stack[*coretypes.Log] // journal of logs that resets on every tx
baseJournal[*coretypes.Log]
txHash common.Hash
txIndex int
}

// NewLogs returns a new `logs` journal.
func NewLogs() Log {
return &logs{
journal: stack.New[*coretypes.Log](initCapacity),
baseJournal: newBaseJournal[*coretypes.Log](initCapacity),
}
}

Expand All @@ -67,7 +65,7 @@ func (l *logs) RegistryKey() string {

// SetTxContext sets the transaction hash and index for the current transaction.
func (l *logs) SetTxContext(thash common.Hash, ti int) {
l.journal = stack.New[*coretypes.Log](initCapacity)
l.baseJournal = newBaseJournal[*coretypes.Log](initCapacity)
// Set the transaction hash and index.
l.txHash = thash
l.txIndex = ti
Expand All @@ -82,65 +80,49 @@ func (l *logs) TxIndex() int {
func (l *logs) AddLog(log *coretypes.Log) {
log.TxHash = l.txHash
log.TxIndex = uint(l.txIndex)
l.journal.Push(log)
l.Push(log)
}

// Logs returns the logs for the current tx with the existing metadata.
func (l *logs) Logs() []*coretypes.Log {
size := l.journal.Size()
size := l.Size()
buf := make([]*coretypes.Log, size)
for i := 0; i < size; i++ {
buf[i] = l.journal.PeekAt(i)
buf[i] = l.PeekAt(i)
}
return buf
}

// GetLogs returns the logs for the tx with the given metadata.
func (l *logs) GetLogs(_ common.Hash, blockNumber uint64, blockHash common.Hash) []*coretypes.Log {
size := l.journal.Size()
size := l.Size()
buf := make([]*coretypes.Log, size)
for i := 0; i < size; i++ {
buf[i] = l.journal.PeekAt(i)
buf[i] = l.PeekAt(i)
buf[i].BlockHash = blockHash
buf[i].BlockNumber = blockNumber
}
return buf
}

// Snapshot takes a snapshot of the `Logs` store.
//
// Snapshot implements `libtypes.Snapshottable`.
func (l *logs) Snapshot() int {
return l.journal.Size()
}

// RevertToSnapshot reverts the `Logs` store to a given snapshot id.
//
// RevertToSnapshot implements `libtypes.Snapshottable`.
func (l *logs) RevertToSnapshot(id int) {
l.journal.PopToSize(id)
}

// Finalize clears the journal of the tx logs.
//
// Finalize implements `libtypes.Controllable`.
func (l *logs) Finalize() {}

// Clone implements `libtypes.Cloneable`.
func (l *logs) Clone() Log {
capacity := l.journal.Capacity()
size := l.journal.Size()
clone := &logs{
journal: stack.New[*coretypes.Log](capacity),
txHash: l.txHash,
txIndex: l.txIndex,
baseJournal: newBaseJournal[*coretypes.Log](l.Capacity()),
txHash: l.txHash,
txIndex: l.txIndex,
}

// copy every individual log from the journal
for i := 0; i < size; i++ {
for i := 0; i < l.Size(); i++ {
cpy := new(coretypes.Log)
*cpy = *l.journal.PeekAt(i)
clone.journal.Push(cpy)
*cpy = *l.PeekAt(i)
clone.Push(cpy)
}

return clone
Expand Down
Loading