Skip to content

Commit

Permalink
Merge pull request ethereum#38 from OffchainLabs/init-cache
Browse files Browse the repository at this point in the history
Stylus Init Cache
  • Loading branch information
rachel-bousfield authored Apr 15, 2024
2 parents 2bef373 + 143049b commit 64277ff
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 4 deletions.
22 changes: 22 additions & 0 deletions common/lru/basiclru_arbitrum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

// Package lru implements generically-typed LRU caches.
package lru

func (c *BasicLRU[K, V]) Capacity() int {
return c.cap
}
37 changes: 36 additions & 1 deletion core/state/journal_arbitrum.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package state

import "github.com/ethereum/go-ethereum/common"
import (
"github.com/ethereum/go-ethereum/common"
)

type wasmActivation struct {
moduleHash common.Hash
Expand All @@ -13,3 +15,36 @@ func (ch wasmActivation) revert(s *StateDB) {
func (ch wasmActivation) dirtied() *common.Address {
return nil
}

// Updates the Rust-side recent program cache
var CacheWasmRust func(asm []byte, moduleHash common.Hash, version uint16, debug bool) = func([]byte, common.Hash, uint16, bool) {}
var EvictWasmRust func(moduleHash common.Hash, version uint16, debug bool) = func(common.Hash, uint16, bool) {}

type CacheWasm struct {
ModuleHash common.Hash
Version uint16
Debug bool
}

func (ch CacheWasm) revert(s *StateDB) {
EvictWasmRust(ch.ModuleHash, ch.Version, ch.Debug)
}

func (ch CacheWasm) dirtied() *common.Address {
return nil
}

type EvictWasm struct {
ModuleHash common.Hash
Version uint16
Debug bool
}

func (ch EvictWasm) revert(s *StateDB) {
asm := s.GetActivatedAsm(ch.ModuleHash) // only happens in native mode
CacheWasmRust(asm, ch.ModuleHash, ch.Version, ch.Debug)
}

func (ch EvictWasm) dirtied() *common.Address {
return nil
}
2 changes: 2 additions & 0 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
openWasmPages: 0,
everWasmPages: 0,
activatedWasms: make(map[common.Hash]*ActivatedWasm),
recentWasms: NewRecentWasms(),
},

db: db,
Expand Down Expand Up @@ -725,6 +726,7 @@ func (s *StateDB) Copy() *StateDB {
arbExtraData: &ArbitrumExtraData{
unexpectedBalanceDelta: new(big.Int).Set(s.arbExtraData.unexpectedBalanceDelta),
activatedWasms: make(map[common.Hash]*ActivatedWasm, len(s.arbExtraData.activatedWasms)),
recentWasms: s.arbExtraData.recentWasms.Copy(),
openWasmPages: s.arbExtraData.openWasmPages,
everWasmPages: s.arbExtraData.everWasmPages,
},
Expand Down
51 changes: 51 additions & 0 deletions core/state/statedb_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"runtime"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
Expand Down Expand Up @@ -155,6 +156,7 @@ type ArbitrumExtraData struct {
openWasmPages uint16 // number of pages currently open
everWasmPages uint16 // largest number of pages ever allocated during this tx's execution
activatedWasms map[common.Hash]*ActivatedWasm // newly activated WASMs
recentWasms RecentWasms
}

func (s *StateDB) SetArbFinalizer(f func(*ArbitrumExtraData)) {
Expand Down Expand Up @@ -246,3 +248,52 @@ func (s *StateDB) RecordProgram(moduleHash common.Hash) {
func (s *StateDB) UserWasms() UserWasms {
return s.arbExtraData.userWasms
}

func (s *StateDB) RecordCacheWasm(wasm CacheWasm) {
s.journal.entries = append(s.journal.entries, wasm)
}

func (s *StateDB) RecordEvictWasm(wasm EvictWasm) {
s.journal.entries = append(s.journal.entries, wasm)
}

func (s *StateDB) GetRecentWasms() RecentWasms {
return s.arbExtraData.recentWasms
}

// Type for managing recent program access.
// The cache contained is discarded at the end of each block.
type RecentWasms struct {
cache *lru.BasicLRU[common.Hash, struct{}]
}

// Creates an un uninitialized cache
func NewRecentWasms() RecentWasms {
return RecentWasms{cache: nil}
}

// Inserts a new item, returning true if already present.
func (p RecentWasms) Insert(item common.Hash, retain uint16) bool {
if p.cache == nil {
cache := lru.NewBasicLRU[common.Hash, struct{}](int(retain))
p.cache = &cache
}
if _, hit := p.cache.Get(item); hit {
println("hit!")
return hit
}
p.cache.Add(item, struct{}{})
return false
}

// Copies all entries into a new LRU.
func (p RecentWasms) Copy() RecentWasms {
if p.cache == nil {
return NewRecentWasms()
}
cache := lru.NewBasicLRU[common.Hash, struct{}](p.cache.Capacity())
for _, item := range p.cache.Keys() {
cache.Add(item, struct{}{})
}
return RecentWasms{cache: &cache}
}
11 changes: 9 additions & 2 deletions core/types/arbitrum_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ import (
var ArbosAddress = common.HexToAddress("0xa4b05")
var ArbosStateAddress = common.HexToAddress("0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
var ArbSysAddress = common.HexToAddress("0x64")
var ArbGasInfoAddress = common.HexToAddress("0x6c")
var ArbRetryableTxAddress = common.HexToAddress("0x6e")
var ArbInfoAddress = common.HexToAddress("0x65")
var ArbAddressTableAddress = common.HexToAddress("0x66")
var ArbBLSAddress = common.HexToAddress("0x67")
var ArbFunctionTableAddress = common.HexToAddress("0x68")
var ArbosTestAddress = common.HexToAddress("0x69")
var ArbGasInfoAddress = common.HexToAddress("0x6c")
var ArbOwnerPublicAddress = common.HexToAddress("0x6b")
var ArbAggregatorAddress = common.HexToAddress("0x6d")
var ArbRetryableTxAddress = common.HexToAddress("0x6e")
var ArbStatisticsAddress = common.HexToAddress("0x6f")
var ArbOwnerAddress = common.HexToAddress("0x70")
var ArbWasmAddress = common.HexToAddress("0x71")
var ArbWasmCacheAddress = common.HexToAddress("0x72")
var NodeInterfaceAddress = common.HexToAddress("0xc8")
var NodeInterfaceDebugAddress = common.HexToAddress("0xc9")
var ArbDebugAddress = common.HexToAddress("0xff")
Expand Down
5 changes: 4 additions & 1 deletion core/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ import (

// StateDB is an EVM database for full state querying.
type StateDB interface {
// Arbitrum: manage compiled wasms
// Arbitrum: manage Stylus wasms
ActivateWasm(moduleHash common.Hash, asm, module []byte)
GetActivatedAsm(moduleHash common.Hash) (asm []byte)
GetActivatedModule(moduleHash common.Hash) (module []byte)
RecordCacheWasm(wasm state.CacheWasm)
RecordEvictWasm(wasm state.EvictWasm)
GetRecentWasms() state.RecentWasms

// Arbitrum: track stylus's memory footprint
GetStylusPages() (uint16, uint16)
Expand Down

0 comments on commit 64277ff

Please sign in to comment.