Skip to content

Commit

Permalink
rawdb: add support for multiple compile targets
Browse files Browse the repository at this point in the history
  • Loading branch information
magicxyyz committed Jul 11, 2024
1 parent b85c247 commit 4027003
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 50 deletions.
79 changes: 73 additions & 6 deletions core/rawdb/accessors_state_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,82 @@ import (
"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)
const (
AsmArm = "arm"
AsmX86 = "x86"
AsmHost = "host"
)

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

func ReadActivatedModule(db ethdb.KeyValueReader, moduleHash common.Hash) []byte {
key := activatedKey(activatedModulePrefix, moduleHash)
module, err := db.Get(key[:])
if err != nil {
return nil
}
return module
}

// Stores the activated asm for a given arch and moduleHash
func WriteActivatedAsm(db ethdb.KeyValueWriter, arch string, moduleHash common.Hash, asm []byte) {
var prefix []byte
switch arch {
case AsmArm:
prefix = activatedAsmArmPrefix
case AsmX86:
prefix = activatedAsmX86Prefix
case AsmHost:
prefix = activatedAsmHostPrefix
default:
log.Crit("Failed to store activated wasm asm, invalid arch specified", "arch", arch)
}
key := activatedKey(prefix, moduleHash)
if err := db.Put(key[:], asm); err != nil {
log.Crit("Failed to store activated wasm asm", "err", err)
}
}

key = ActivatedModuleKey(moduleHash)
if err := db.Put(key[:], module); err != nil {
log.Crit("Failed to store activated wasm module", "err", err)
func ReadActivatedAsm(db ethdb.KeyValueReader, arch string, moduleHash common.Hash) []byte {
var prefix []byte
switch arch {
case AsmArm:
prefix = activatedAsmArmPrefix
case AsmX86:
prefix = activatedAsmX86Prefix
case AsmHost:
prefix = activatedAsmHostPrefix
default:
log.Crit("Failed to store activated wasm asm, invalid arch specified", "arch", arch)
}
key := activatedKey(prefix, moduleHash)
asm, err := db.Get(key[:])
if err != nil {
return nil
}
return asm
}

// 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, if the correspoding key is not foud returns version 0
func ReadWasmSchemaVersion(db ethdb.KeyValueReader) byte {
version, err := db.Get(wasmSchemaVersionKey)
if err != nil || len(version) == 0 {
return 0
} else if len(version) != 1 {
log.Crit("Invalid wasm schema version in database", "version", version)
}
return version[0]
}
40 changes: 11 additions & 29 deletions core/rawdb/schema_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,30 @@
package rawdb

import (
"bytes"

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

const wasmSchemaVersion byte = 0x01

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

// TODO do we need 0x00 prefix? or even: do we need also 'w' there?
activatedAsmArmPrefix = []byte{0x00, 'w', 'r'} // (prefix, moduleHash) -> stylus asm for ARM system
activatedAsmX86Prefix = []byte{0x00, 'w', 'x'} // (prefix, moduleHash) -> stylus asm for x86 system
activatedAsmHostPrefix = []byte{0x00, 'w', 'h'} // (prefix, moduleHash) -> stylus asm for system other then ARM and x86
activatedModulePrefix = []byte{0x00, 'w', 'm'} // (prefix, moduleHash) -> stylus module
)

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

type WasmKey = [WasmKeyLen]byte

func ActivatedAsmKey(moduleHash common.Hash) WasmKey {
return newWasmKey(activatedAsmPrefix, moduleHash)
}

func ActivatedModuleKey(moduleHash common.Hash) WasmKey {
return newWasmKey(activatedModulePrefix, moduleHash)
}

// key = prefix + moduleHash
func newWasmKey(prefix []byte, moduleHash common.Hash) WasmKey {
func activatedKey(prefix []byte, moduleHash common.Hash) WasmKey {
var key WasmKey
copy(key[:3], prefix)
copy(key[3:], 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):])
}
3 changes: 2 additions & 1 deletion core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,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)
ActivatedAsm(arch string, moduleHash common.Hash) (asm []byte, err error)
ActivatedModule(moduleHash common.Hash) (module []byte, err error)
WasmStore() ethdb.KeyValueStore
WasmCacheTag() uint32
Expand Down Expand Up @@ -196,6 +196,7 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {

type cachingDB struct {
// Arbitrum
// asm cache caches only asm compiled for the machine architecture
activatedAsmCache *lru.SizeConstrainedCache[common.Hash, []byte]
activatedModuleCache *lru.SizeConstrainedCache[common.Hash, []byte]
wasmTag uint32
Expand Down
16 changes: 3 additions & 13 deletions core/state/database_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
)

func (db *cachingDB) ActivatedAsm(moduleHash common.Hash) ([]byte, error) {
func (db *cachingDB) ActivatedAsm(arch string, moduleHash common.Hash) ([]byte, error) {
if asm, _ := db.activatedAsmCache.Get(moduleHash); 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 {
if asm := rawdb.ReadActivatedAsm(arch, moduleHash); len(asm) > 0 {

Check failure on line 14 in core/state/database_arbitrum.go

View workflow job for this annotation

GitHub Actions / run-tests

not enough arguments in call to rawdb.ReadActivatedAsm

Check failure on line 14 in core/state/database_arbitrum.go

View workflow job for this annotation

GitHub Actions / run-linter

not enough arguments in call to rawdb.ReadActivatedAsm

Check failure on line 14 in core/state/database_arbitrum.go

View workflow job for this annotation

GitHub Actions / run-linter

not enough arguments in call to rawdb.ReadActivatedAsm
db.activatedAsmCache.Add(moduleHash, asm)
return asm, nil
}
Expand All @@ -27,12 +22,7 @@ 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 {
if module := rawdb.ReadActivatedModule(db.wasmdb, moduleHash); len(module) > 0 {
db.activatedModuleCache.Add(moduleHash, module)
return module, nil
}
Expand Down
2 changes: 1 addition & 1 deletion core/state/statedb_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var (
)

type ActivatedWasm struct {
Asm []byte
Asm map[string][]byte
Module []byte
}

Expand Down

0 comments on commit 4027003

Please sign in to comment.