Skip to content

Commit

Permalink
Merge branch 'master' into merge-1.14.0
Browse files Browse the repository at this point in the history
  • Loading branch information
amsanghi authored Aug 20, 2024
2 parents 4b4742a + 85dc1b7 commit d251082
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 127 deletions.
91 changes: 85 additions & 6 deletions core/rawdb/accessors_state_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,99 @@
package rawdb

import (
"fmt"
"runtime"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
)

// Stores the activated asm and module for a given codeHash
func WriteActivation(db ethdb.KeyValueWriter, moduleHash common.Hash, asm, module []byte) {
key := ActivatedAsmKey(moduleHash)
type Target string

const (
TargetWavm Target = "wavm"
TargetArm64 Target = "arm64"
TargetAmd64 Target = "amd64"
TargetHost Target = "host"
)

func LocalTarget() Target {
if runtime.GOOS == "linux" {
switch runtime.GOARCH {
case "arm64":
return TargetArm64
case "amd64":
return TargetAmd64
}
}
return TargetHost
}

func (t Target) keyPrefix() (WasmPrefix, error) {
var prefix WasmPrefix
switch t {
case TargetWavm:
prefix = activatedAsmWavmPrefix
case TargetArm64:
prefix = activatedAsmArmPrefix
case TargetAmd64:
prefix = activatedAsmX86Prefix
case TargetHost:
prefix = activatedAsmHostPrefix
default:
return WasmPrefix{}, fmt.Errorf("invalid target: %v", t)
}
return prefix, nil
}

func (t Target) IsValid() bool {
_, err := t.keyPrefix()
return err == nil
}

var Targets = []Target{TargetWavm, TargetArm64, TargetAmd64, TargetHost}

func WriteActivation(db ethdb.KeyValueWriter, moduleHash common.Hash, asmMap map[Target][]byte) {
for target, asm := range asmMap {
WriteActivatedAsm(db, target, moduleHash, asm)
}
}

// Stores the activated asm for a given moduleHash and target
func WriteActivatedAsm(db ethdb.KeyValueWriter, target Target, moduleHash common.Hash, asm []byte) {
prefix, err := target.keyPrefix()
if err != nil {
log.Crit("Failed to store activated wasm asm", "err", err)
}
key := activatedKey(prefix, moduleHash)
if err := db.Put(key[:], asm); err != nil {
log.Crit("Failed to store activated wasm asm", "err", err)
}
}

// Retrieves the activated asm for a given moduleHash and target
func ReadActivatedAsm(db ethdb.KeyValueReader, target Target, moduleHash common.Hash) []byte {
prefix, err := target.keyPrefix()
if err != nil {
log.Crit("Failed to read activated wasm asm", "err", err)
}
key := activatedKey(prefix, moduleHash)
asm, err := db.Get(key[:])
if err != nil {
return nil
}
return asm
}

key = ActivatedModuleKey(moduleHash)
if err := db.Put(key[:], module); err != nil {
log.Crit("Failed to store activated wasm module", "err", err)
// Stores wasm schema version
func WriteWasmSchemaVersion(db ethdb.KeyValueWriter) {
if err := db.Put(wasmSchemaVersionKey, []byte{WasmSchemaVersion}); err != nil {
log.Crit("Failed to store wasm schema version", "err", err)
}
}

// Retrieves wasm schema version
func ReadWasmSchemaVersion(db ethdb.KeyValueReader) ([]byte, error) {
return db.Get(wasmSchemaVersionKey)
}
53 changes: 23 additions & 30 deletions core/rawdb/schema_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,41 @@
package rawdb

import (
"bytes"

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

var (
activatedAsmPrefix = []byte{0x00, 'w', 'a'} // (prefix, moduleHash) -> stylus asm
activatedModulePrefix = []byte{0x00, 'w', 'm'} // (prefix, moduleHash) -> stylus module
)
const WasmSchemaVersion byte = 0x01

const WasmPrefixLen = 3

// WasmKeyLen = CompiledWasmCodePrefix + moduleHash
const WasmKeyLen = 3 + 32
const WasmKeyLen = WasmPrefixLen + common.HashLength

type WasmPrefix = [WasmPrefixLen]byte
type WasmKey = [WasmKeyLen]byte

func ActivatedAsmKey(moduleHash common.Hash) WasmKey {
return newWasmKey(activatedAsmPrefix, moduleHash)
}
var (
wasmSchemaVersionKey = []byte("WasmSchemaVersion")

// 0x00 prefix to avoid conflicts when wasmdb is not separate database
activatedAsmWavmPrefix = WasmPrefix{0x00, 'w', 'w'} // (prefix, moduleHash) -> stylus module (wavm)
activatedAsmArmPrefix = WasmPrefix{0x00, 'w', 'r'} // (prefix, moduleHash) -> stylus asm for ARM system
activatedAsmX86Prefix = WasmPrefix{0x00, 'w', 'x'} // (prefix, moduleHash) -> stylus asm for x86 system
activatedAsmHostPrefix = WasmPrefix{0x00, 'w', 'h'} // (prefix, moduleHash) -> stylus asm for system other then ARM and x86
)

func ActivatedModuleKey(moduleHash common.Hash) WasmKey {
return newWasmKey(activatedModulePrefix, moduleHash)
func DeprecatedPrefixesV0() (keyPrefixes [][]byte, keyLength int) {
return [][]byte{
// deprecated prefixes, used in version 0x00, purged in version 0x01
[]byte{0x00, 'w', 'a'}, // ActivatedAsmPrefix
[]byte{0x00, 'w', 'm'}, // ActivatedModulePrefix
}, 3 + 32
}

// key = prefix + moduleHash
func newWasmKey(prefix []byte, moduleHash common.Hash) WasmKey {
func activatedKey(prefix WasmPrefix, moduleHash common.Hash) WasmKey {
var key WasmKey
copy(key[:3], prefix)
copy(key[3:], moduleHash[:])
copy(key[:WasmPrefixLen], prefix[:])
copy(key[WasmPrefixLen:], moduleHash[:])
return key
}

func IsActivatedAsmKey(key []byte) (bool, common.Hash) {
return extractWasmKey(activatedAsmPrefix, key)
}

func IsActivatedModuleKey(key []byte) (bool, common.Hash) {
return extractWasmKey(activatedModulePrefix, key)
}

func extractWasmKey(prefix, key []byte) (bool, common.Hash) {
if !bytes.HasPrefix(key, prefix) || len(key) != WasmKeyLen {
return false, common.Hash{}
}
return true, common.BytesToHash(key[len(prefix):])
}
23 changes: 12 additions & 11 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ const (
// Database wraps access to tries and contract code.
type Database interface {
// Arbitrum: Read activated Stylus contracts
ActivatedAsm(moduleHash common.Hash) (asm []byte, err error)
ActivatedModule(moduleHash common.Hash) (module []byte, err error)
ActivatedAsm(target rawdb.Target, moduleHash common.Hash) (asm []byte, err error)
WasmStore() ethdb.KeyValueStore
WasmCacheTag() uint32

Expand Down Expand Up @@ -164,9 +163,8 @@ func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database {
wasmdb, wasmTag := db.WasmDataBase()
cdb := &cachingDB{
// Arbitrum only
activatedAsmCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize),
activatedModuleCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize),
wasmTag: wasmTag,
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
wasmTag: wasmTag,

disk: db,
wasmdb: wasmdb,
Expand All @@ -182,9 +180,8 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database
wasmdb, wasmTag := db.WasmDataBase()
cdb := &cachingDB{
// Arbitrum only
activatedAsmCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize),
activatedModuleCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize),
wasmTag: wasmTag,
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
wasmTag: wasmTag,

disk: db,
wasmdb: wasmdb,
Expand All @@ -195,11 +192,15 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database
return cdb
}

type activatedAsmCacheKey struct {
moduleHash common.Hash
target rawdb.Target
}

type cachingDB struct {
// Arbitrum
activatedAsmCache *lru.SizeConstrainedCache[common.Hash, []byte]
activatedModuleCache *lru.SizeConstrainedCache[common.Hash, []byte]
wasmTag uint32
activatedAsmCache *lru.SizeConstrainedCache[activatedAsmCacheKey, []byte]
wasmTag uint32

disk ethdb.KeyValueStore
wasmdb ethdb.KeyValueStore
Expand Down
30 changes: 5 additions & 25 deletions core/state/database_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,14 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
)

func (db *cachingDB) ActivatedAsm(moduleHash common.Hash) ([]byte, error) {
if asm, _ := db.activatedAsmCache.Get(moduleHash); len(asm) > 0 {
func (db *cachingDB) ActivatedAsm(target rawdb.Target, moduleHash common.Hash) ([]byte, error) {
cacheKey := activatedAsmCacheKey{moduleHash, target}
if asm, _ := db.activatedAsmCache.Get(cacheKey); len(asm) > 0 {
return asm, nil
}
wasmKey := rawdb.ActivatedAsmKey(moduleHash)
asm, err := db.wasmdb.Get(wasmKey[:])
if err != nil {
return nil, err
}
if len(asm) > 0 {
db.activatedAsmCache.Add(moduleHash, asm)
if asm := rawdb.ReadActivatedAsm(db.wasmdb, target, moduleHash); len(asm) > 0 {
db.activatedAsmCache.Add(cacheKey, asm)
return asm, nil
}
return nil, errors.New("not found")
}

func (db *cachingDB) ActivatedModule(moduleHash common.Hash) ([]byte, error) {
if module, _ := db.activatedModuleCache.Get(moduleHash); len(module) > 0 {
return module, nil
}
wasmKey := rawdb.ActivatedModuleKey(moduleHash)
module, err := db.wasmdb.Get(wasmKey[:])
if err != nil {
return nil, err
}
if len(module) > 0 {
db.activatedModuleCache.Add(moduleHash, module)
return module, nil
}
return nil, errors.New("not found")
}
3 changes: 2 additions & 1 deletion core/state/journal_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state

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

type wasmActivation struct {
Expand Down Expand Up @@ -43,7 +44,7 @@ type EvictWasm struct {
}

func (ch EvictWasm) revert(s *StateDB) {
asm, err := s.TryGetActivatedAsm(ch.ModuleHash) // only happens in native mode
asm, err := s.TryGetActivatedAsm(rawdb.LocalTarget(), ch.ModuleHash) // only happens in native mode
if err == nil && len(asm) != 0 {
//if we failed to get it - it's not in the current rust cache
CacheWasmRust(asm, ch.ModuleHash, ch.Version, ch.Tag, ch.Debug)
Expand Down
14 changes: 7 additions & 7 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
unexpectedBalanceDelta: new(big.Int),
openWasmPages: 0,
everWasmPages: 0,
activatedWasms: make(map[common.Hash]*ActivatedWasm),
activatedWasms: make(map[common.Hash]ActivatedWasm),
recentWasms: NewRecentWasms(),
},

Expand Down Expand Up @@ -727,7 +727,7 @@ func (s *StateDB) Copy() *StateDB {
state := &StateDB{
arbExtraData: &ArbitrumExtraData{
unexpectedBalanceDelta: new(big.Int).Set(s.arbExtraData.unexpectedBalanceDelta),
activatedWasms: make(map[common.Hash]*ActivatedWasm, len(s.arbExtraData.activatedWasms)),
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 Expand Up @@ -817,9 +817,9 @@ func (s *StateDB) Copy() *StateDB {
state.arbExtraData.userWasms[call] = wasm
}
}
for moduleHash, info := range s.arbExtraData.activatedWasms {
for moduleHash, asmMap := range s.arbExtraData.activatedWasms {
// It's fine to skip a deep copy since activations are immutable.
state.arbExtraData.activatedWasms[moduleHash] = info
state.arbExtraData.activatedWasms[moduleHash] = asmMap
}

// If there's a prefetcher running, make an inactive copy of it that can
Expand Down Expand Up @@ -1277,11 +1277,11 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
}

// Arbitrum: write Stylus programs to disk
for moduleHash, info := range s.arbExtraData.activatedWasms {
rawdb.WriteActivation(wasmCodeWriter, moduleHash, info.Asm, info.Module)
for moduleHash, asmMap := range s.arbExtraData.activatedWasms {
rawdb.WriteActivation(wasmCodeWriter, moduleHash, asmMap)
}
if len(s.arbExtraData.activatedWasms) > 0 {
s.arbExtraData.activatedWasms = make(map[common.Hash]*ActivatedWasm)
s.arbExtraData.activatedWasms = make(map[common.Hash]ActivatedWasm)
}

if codeWriter.ValueSize() > 0 {
Expand Down
Loading

0 comments on commit d251082

Please sign in to comment.