Skip to content

Commit fb79423

Browse files
authored
Merge pull request #353 from OffchainLabs/cross-compile
support cross-compilation of stylus programs
2 parents 85dc1b7 + 81114dd commit fb79423

File tree

11 files changed

+72
-46
lines changed

11 files changed

+72
-46
lines changed

arbitrum/apibackend.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fal
105105
// discard stylus-tag on any call made from api database
106106
dbForAPICalls := backend.chainDb
107107
wasmStore, tag := backend.chainDb.WasmDataBase()
108-
if tag != 0 {
109-
dbForAPICalls = rawdb.WrapDatabaseWithWasm(backend.chainDb, wasmStore, 0)
108+
if tag != 0 || len(backend.chainDb.WasmTargets()) > 1 {
109+
dbForAPICalls = rawdb.WrapDatabaseWithWasm(backend.chainDb, wasmStore, 0, []ethdb.WasmTarget{rawdb.LocalTarget()})
110110
}
111111
backend.apiBackend = &APIBackend{
112112
b: backend,

arbitrum/recordingdb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func (r *RecordingDatabase) PrepareRecording(ctx context.Context, lastBlockHeade
269269
defer func() { r.Dereference(finalDereference) }()
270270
recordingKeyValue := newRecordingKV(r.db.TrieDB(), r.db.DiskDB())
271271

272-
recordingStateDatabase := state.NewDatabase(rawdb.WrapDatabaseWithWasm(rawdb.NewDatabase(recordingKeyValue), r.db.WasmStore(), 0))
272+
recordingStateDatabase := state.NewDatabase(rawdb.WrapDatabaseWithWasm(rawdb.NewDatabase(recordingKeyValue), r.db.WasmStore(), 0, r.db.WasmTargets()))
273273
var prevRoot common.Hash
274274
if lastBlockHeader != nil {
275275
prevRoot = lastBlockHeader.Root

core/rawdb/accessors_state_arbitrum.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,14 @@ import (
2525
"github.com/ethereum/go-ethereum/log"
2626
)
2727

28-
type Target string
29-
3028
const (
31-
TargetWavm Target = "wavm"
32-
TargetArm64 Target = "arm64"
33-
TargetAmd64 Target = "amd64"
34-
TargetHost Target = "host"
29+
TargetWavm ethdb.WasmTarget = "wavm"
30+
TargetArm64 ethdb.WasmTarget = "arm64"
31+
TargetAmd64 ethdb.WasmTarget = "amd64"
32+
TargetHost ethdb.WasmTarget = "host"
3533
)
3634

37-
func LocalTarget() Target {
35+
func LocalTarget() ethdb.WasmTarget {
3836
if runtime.GOOS == "linux" {
3937
switch runtime.GOARCH {
4038
case "arm64":
@@ -46,9 +44,9 @@ func LocalTarget() Target {
4644
return TargetHost
4745
}
4846

49-
func (t Target) keyPrefix() (WasmPrefix, error) {
47+
func activatedAsmKeyPrefix(target ethdb.WasmTarget) (WasmPrefix, error) {
5048
var prefix WasmPrefix
51-
switch t {
49+
switch target {
5250
case TargetWavm:
5351
prefix = activatedAsmWavmPrefix
5452
case TargetArm64:
@@ -58,27 +56,25 @@ func (t Target) keyPrefix() (WasmPrefix, error) {
5856
case TargetHost:
5957
prefix = activatedAsmHostPrefix
6058
default:
61-
return WasmPrefix{}, fmt.Errorf("invalid target: %v", t)
59+
return WasmPrefix{}, fmt.Errorf("invalid target: %v", target)
6260
}
6361
return prefix, nil
6462
}
6563

66-
func (t Target) IsValid() bool {
67-
_, err := t.keyPrefix()
64+
func IsSupportedWasmTarget(target ethdb.WasmTarget) bool {
65+
_, err := activatedAsmKeyPrefix(target)
6866
return err == nil
6967
}
7068

71-
var Targets = []Target{TargetWavm, TargetArm64, TargetAmd64, TargetHost}
72-
73-
func WriteActivation(db ethdb.KeyValueWriter, moduleHash common.Hash, asmMap map[Target][]byte) {
69+
func WriteActivation(db ethdb.KeyValueWriter, moduleHash common.Hash, asmMap map[ethdb.WasmTarget][]byte) {
7470
for target, asm := range asmMap {
7571
WriteActivatedAsm(db, target, moduleHash, asm)
7672
}
7773
}
7874

7975
// Stores the activated asm for a given moduleHash and target
80-
func WriteActivatedAsm(db ethdb.KeyValueWriter, target Target, moduleHash common.Hash, asm []byte) {
81-
prefix, err := target.keyPrefix()
76+
func WriteActivatedAsm(db ethdb.KeyValueWriter, target ethdb.WasmTarget, moduleHash common.Hash, asm []byte) {
77+
prefix, err := activatedAsmKeyPrefix(target)
8278
if err != nil {
8379
log.Crit("Failed to store activated wasm asm", "err", err)
8480
}
@@ -89,8 +85,8 @@ func WriteActivatedAsm(db ethdb.KeyValueWriter, target Target, moduleHash common
8985
}
9086

9187
// Retrieves the activated asm for a given moduleHash and target
92-
func ReadActivatedAsm(db ethdb.KeyValueReader, target Target, moduleHash common.Hash) []byte {
93-
prefix, err := target.keyPrefix()
88+
func ReadActivatedAsm(db ethdb.KeyValueReader, target ethdb.WasmTarget, moduleHash common.Hash) []byte {
89+
prefix, err := activatedAsmKeyPrefix(target)
9490
if err != nil {
9591
log.Crit("Failed to read activated wasm asm", "err", err)
9692
}

core/rawdb/database.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ type freezerdb struct {
4242
ethdb.AncientStore
4343
}
4444

45-
// AncientDatadir returns the path of root ancient directory.
4645
func (frdb *freezerdb) WasmDataBase() (ethdb.KeyValueStore, uint32) {
4746
return frdb, 0
4847
}
4948

49+
func (frdb *freezerdb) WasmTargets() []ethdb.WasmTarget {
50+
return nil
51+
}
52+
5053
// AncientDatadir returns the path of root ancient directory.
5154
func (frdb *freezerdb) AncientDatadir() (string, error) {
5255
return frdb.ancientRoot, nil
@@ -170,11 +173,14 @@ func (db *nofreezedb) AncientDatadir() (string, error) {
170173
return "", errNotSupported
171174
}
172175

173-
// AncientDatadir returns the path of root ancient directory.
174176
func (db *nofreezedb) WasmDataBase() (ethdb.KeyValueStore, uint32) {
175177
return db, 0
176178
}
177179

180+
func (db *nofreezedb) WasmTargets() []ethdb.WasmTarget {
181+
return nil
182+
}
183+
178184
// NewDatabase creates a high level database on top of a given key-value data
179185
// store without a freezer moving immutable chain segments into cold storage.
180186
func NewDatabase(db ethdb.KeyValueStore) ethdb.Database {
@@ -185,12 +191,17 @@ type dbWithWasmEntry struct {
185191
ethdb.Database
186192
wasmDb ethdb.KeyValueStore
187193
wasmCacheTag uint32
194+
wasmTargets []ethdb.WasmTarget
188195
}
189196

190197
func (db *dbWithWasmEntry) WasmDataBase() (ethdb.KeyValueStore, uint32) {
191198
return db.wasmDb, db.wasmCacheTag
192199
}
193200

201+
func (db *dbWithWasmEntry) WasmTargets() []ethdb.WasmTarget {
202+
return db.wasmTargets
203+
}
204+
194205
func (db *dbWithWasmEntry) Close() error {
195206
dbErr := db.Database.Close()
196207
wasmErr := db.wasmDb.Close()
@@ -200,8 +211,8 @@ func (db *dbWithWasmEntry) Close() error {
200211
return wasmErr
201212
}
202213

203-
func WrapDatabaseWithWasm(db ethdb.Database, wasm ethdb.KeyValueStore, cacheTag uint32) ethdb.Database {
204-
return &dbWithWasmEntry{db, wasm, cacheTag}
214+
func WrapDatabaseWithWasm(db ethdb.Database, wasm ethdb.KeyValueStore, cacheTag uint32, targets []ethdb.WasmTarget) ethdb.Database {
215+
return &dbWithWasmEntry{db, wasm, cacheTag, targets}
205216
}
206217

207218
// resolveChainFreezerDir is a helper function which resolves the absolute path

core/rawdb/table.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ func (t *table) WasmDataBase() (ethdb.KeyValueStore, uint32) {
4444
return t.db.WasmDataBase()
4545
}
4646

47+
func (t *table) WasmTargets() []ethdb.WasmTarget {
48+
return t.db.WasmTargets()
49+
}
50+
4751
// Has retrieves if a prefixed version of a key is present in the database.
4852
func (t *table) Has(key []byte) (bool, error) {
4953
return t.db.Has(append([]byte(t.prefix), key...))

core/state/database.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ const (
5353
// Database wraps access to tries and contract code.
5454
type Database interface {
5555
// Arbitrum: Read activated Stylus contracts
56-
ActivatedAsm(target rawdb.Target, moduleHash common.Hash) (asm []byte, err error)
56+
ActivatedAsm(target ethdb.WasmTarget, moduleHash common.Hash) (asm []byte, err error)
5757
WasmStore() ethdb.KeyValueStore
5858
WasmCacheTag() uint32
59+
WasmTargets() []ethdb.WasmTarget
5960

6061
// OpenTrie opens the main account trie.
6162
OpenTrie(root common.Hash) (Trie, error)
@@ -163,8 +164,9 @@ func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database {
163164
wasmdb, wasmTag := db.WasmDataBase()
164165
cdb := &cachingDB{
165166
// Arbitrum only
166-
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
167-
wasmTag: wasmTag,
167+
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
168+
wasmTag: wasmTag,
169+
wasmDatabaseRetriever: db,
168170

169171
disk: db,
170172
wasmdb: wasmdb,
@@ -180,8 +182,9 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database
180182
wasmdb, wasmTag := db.WasmDataBase()
181183
cdb := &cachingDB{
182184
// Arbitrum only
183-
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
184-
wasmTag: wasmTag,
185+
activatedAsmCache: lru.NewSizeConstrainedCache[activatedAsmCacheKey, []byte](activatedWasmCacheSize),
186+
wasmTag: wasmTag,
187+
wasmDatabaseRetriever: db,
185188

186189
disk: db,
187190
wasmdb: wasmdb,
@@ -194,13 +197,14 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database
194197

195198
type activatedAsmCacheKey struct {
196199
moduleHash common.Hash
197-
target rawdb.Target
200+
target ethdb.WasmTarget
198201
}
199202

200203
type cachingDB struct {
201204
// Arbitrum
202-
activatedAsmCache *lru.SizeConstrainedCache[activatedAsmCacheKey, []byte]
203-
wasmTag uint32
205+
activatedAsmCache *lru.SizeConstrainedCache[activatedAsmCacheKey, []byte]
206+
wasmTag uint32
207+
wasmDatabaseRetriever ethdb.WasmDataBaseRetriever
204208

205209
disk ethdb.KeyValueStore
206210
wasmdb ethdb.KeyValueStore
@@ -217,6 +221,10 @@ func (db *cachingDB) WasmCacheTag() uint32 {
217221
return db.wasmTag
218222
}
219223

224+
func (db *cachingDB) WasmTargets() []ethdb.WasmTarget {
225+
return db.wasmDatabaseRetriever.WasmTargets()
226+
}
227+
220228
// OpenTrie opens the main account trie at a specific root hash.
221229
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
222230
if db.triedb.IsVerkle() {

core/state/database_arbitrum.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import (
55

66
"github.com/ethereum/go-ethereum/common"
77
"github.com/ethereum/go-ethereum/core/rawdb"
8+
"github.com/ethereum/go-ethereum/ethdb"
89
)
910

10-
func (db *cachingDB) ActivatedAsm(target rawdb.Target, moduleHash common.Hash) ([]byte, error) {
11+
func (db *cachingDB) ActivatedAsm(target ethdb.WasmTarget, moduleHash common.Hash) ([]byte, error) {
1112
cacheKey := activatedAsmCacheKey{moduleHash, target}
1213
if asm, _ := db.activatedAsmCache.Get(cacheKey); len(asm) > 0 {
1314
return asm, nil

core/state/statedb_arbitrum.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ import (
2727

2828
"github.com/ethereum/go-ethereum/common"
2929
"github.com/ethereum/go-ethereum/common/lru"
30-
"github.com/ethereum/go-ethereum/core/rawdb"
3130
"github.com/ethereum/go-ethereum/core/types"
31+
"github.com/ethereum/go-ethereum/ethdb"
3232
"github.com/ethereum/go-ethereum/log"
3333
"github.com/ethereum/go-ethereum/rlp"
3434
"github.com/ethereum/go-ethereum/trie"
@@ -50,7 +50,7 @@ var (
5050
StylusDiscriminant = []byte{stylusEOFMagic, stylusEOFMagicSuffix, stylusEOFVersion}
5151
)
5252

53-
type ActivatedWasm map[rawdb.Target][]byte
53+
type ActivatedWasm map[ethdb.WasmTarget][]byte
5454

5555
// checks if a valid Stylus prefix is present
5656
func IsStylusProgram(b []byte) bool {
@@ -74,7 +74,7 @@ func NewStylusPrefix(dictionary byte) []byte {
7474
return append(prefix, dictionary)
7575
}
7676

77-
func (s *StateDB) ActivateWasm(moduleHash common.Hash, asmMap map[rawdb.Target][]byte) {
77+
func (s *StateDB) ActivateWasm(moduleHash common.Hash, asmMap map[ethdb.WasmTarget][]byte) {
7878
_, exists := s.arbExtraData.activatedWasms[moduleHash]
7979
if exists {
8080
return
@@ -85,7 +85,7 @@ func (s *StateDB) ActivateWasm(moduleHash common.Hash, asmMap map[rawdb.Target][
8585
})
8686
}
8787

88-
func (s *StateDB) TryGetActivatedAsm(target rawdb.Target, moduleHash common.Hash) ([]byte, error) {
88+
func (s *StateDB) TryGetActivatedAsm(target ethdb.WasmTarget, moduleHash common.Hash) ([]byte, error) {
8989
asmMap, exists := s.arbExtraData.activatedWasms[moduleHash]
9090
if exists {
9191
if asm, exists := asmMap[target]; exists {
@@ -95,7 +95,7 @@ func (s *StateDB) TryGetActivatedAsm(target rawdb.Target, moduleHash common.Hash
9595
return s.db.ActivatedAsm(target, moduleHash)
9696
}
9797

98-
func (s *StateDB) TryGetActivatedAsmMap(targets []rawdb.Target, moduleHash common.Hash) (map[rawdb.Target][]byte, error) {
98+
func (s *StateDB) TryGetActivatedAsmMap(targets []ethdb.WasmTarget, moduleHash common.Hash) (map[ethdb.WasmTarget][]byte, error) {
9999
asmMap := s.arbExtraData.activatedWasms[moduleHash]
100100
if asmMap != nil {
101101
for _, target := range targets {
@@ -106,7 +106,7 @@ func (s *StateDB) TryGetActivatedAsmMap(targets []rawdb.Target, moduleHash commo
106106
return asmMap, nil
107107
}
108108
var err error
109-
asmMap = make(map[rawdb.Target][]byte, len(targets))
109+
asmMap = make(map[ethdb.WasmTarget][]byte, len(targets))
110110
for _, target := range targets {
111111
asm, dbErr := s.db.ActivatedAsm(target, moduleHash)
112112
if dbErr == nil {
@@ -241,7 +241,7 @@ func (s *StateDB) StartRecording() {
241241
s.arbExtraData.userWasms = make(UserWasms)
242242
}
243243

244-
func (s *StateDB) RecordProgram(targets []rawdb.Target, moduleHash common.Hash) {
244+
func (s *StateDB) RecordProgram(targets []ethdb.WasmTarget, moduleHash common.Hash) {
245245
if len(targets) == 0 {
246246
// nothing to record
247247
return

core/vm/interface.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,19 @@ import (
2020
"math/big"
2121

2222
"github.com/ethereum/go-ethereum/common"
23-
"github.com/ethereum/go-ethereum/core/rawdb"
2423
"github.com/ethereum/go-ethereum/core/state"
2524
"github.com/ethereum/go-ethereum/core/types"
25+
"github.com/ethereum/go-ethereum/ethdb"
2626
"github.com/ethereum/go-ethereum/params"
2727
"github.com/holiman/uint256"
2828
)
2929

3030
// StateDB is an EVM database for full state querying.
3131
type StateDB interface {
3232
// Arbitrum: manage Stylus wasms
33-
ActivateWasm(moduleHash common.Hash, asmMap map[rawdb.Target][]byte)
34-
TryGetActivatedAsm(target rawdb.Target, moduleHash common.Hash) (asm []byte, err error)
35-
TryGetActivatedAsmMap(targets []rawdb.Target, moduleHash common.Hash) (asmMap map[rawdb.Target][]byte, err error)
33+
ActivateWasm(moduleHash common.Hash, asmMap map[ethdb.WasmTarget][]byte)
34+
TryGetActivatedAsm(target ethdb.WasmTarget, moduleHash common.Hash) (asm []byte, err error)
35+
TryGetActivatedAsmMap(targets []ethdb.WasmTarget, moduleHash common.Hash) (asmMap map[ethdb.WasmTarget][]byte, err error)
3636
RecordCacheWasm(wasm state.CacheWasm)
3737
RecordEvictWasm(wasm state.EvictWasm)
3838
GetRecentWasms() state.RecentWasms

ethdb/database.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ type AncientStore interface {
178178
io.Closer
179179
}
180180

181+
type WasmTarget string
181182
type WasmDataBaseRetriever interface {
182183
WasmDataBase() (KeyValueStore, uint32)
184+
WasmTargets() []WasmTarget
183185
}
184186

185187
// Database contains all the methods required by the high level database to not

0 commit comments

Comments
 (0)