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

Commit

Permalink
fix(journal): Restructure journals (#1135)
Browse files Browse the repository at this point in the history
  • Loading branch information
itsdevbear authored Sep 22, 2023
1 parent cef9b28 commit d5824bc
Show file tree
Hide file tree
Showing 17 changed files with 143 additions and 183 deletions.
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

0 comments on commit d5824bc

Please sign in to comment.