Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate Stylus Params #215

Merged
merged 3 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions arbos/programs/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ func NewMemoryModel(freePages uint16, pageGas uint16) *MemoryModel {
}
}

func (p Programs) memoryModel() (*MemoryModel, error) {
freePages, err := p.FreePages()
if err != nil {
return nil, err
}
pageGas, err := p.PageGas()

return NewMemoryModel(freePages, pageGas), err
}

// Determines the gas cost of allocating `new` pages given `open` are active and `ever` have ever been.
func (model *MemoryModel) GasCost(new, open, ever uint16) uint64 {
newOpen := arbmath.SaturatingUAdd(open, new)
Expand Down
126 changes: 126 additions & 0 deletions arbos/programs/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2022-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE

package programs

import (
"errors"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/offchainlabs/nitro/arbos/storage"
am "github.com/offchainlabs/nitro/util/arbmath"
)

const MaxWasmSize = 128 * 1024 // max decompressed wasm size (programs are also bounded by compressed size)
const initialStackDepth = 4 * 65536 // 4 page stack.
const InitialFreePages = 2 // 2 pages come free (per tx).
const InitialPageGas = 1000 // linear cost per allocation.
const initialPageRamp = 620674314 // targets 8MB costing 32 million gas, minus the linear term.
const initialPageLimit = 128 // reject wasms with memories larger than 8MB.
const initialInkPrice = 10000 // 1 evm gas buys 10k ink.
const initialMinInitGas = 0 // assume pricer is correct (update in case of emergency)
const initialExpiryDays = 365 // deactivate after 1 year.
const initialKeepaliveDays = 31 // wait a month before allowing reactivation
const initialInitTableBits = 7 // cache the last 128 programs
const initialTrieTableBits = 11 // cache the hottest 1024 slots

// This struct exists to collect the many Stylus configuration parameters into a single word.
// The items here must only be modified in ArbOwner precompile methods (or in ArbOS upgrades).
type StylusParams struct {
backingStorage *storage.Storage
Version uint16 // must only be changed during ArbOS upgrades
InkPrice uint24
MaxStackDepth uint32
FreePages uint16
PageGas uint16
PageRamp uint64
PageLimit uint16
MinInitGas uint16
ExpiryDays uint16
KeepaliveDays uint16
InitTableBits uint8
TrieTableBits uint8
}

// Provides a view of the Stylus parameters. Call Save() to persist.
// Note: this method never returns nil.
func (p Programs) Params() (*StylusParams, error) {
sto := p.backingStorage.OpenSubStorage(paramsKey)

// assume read is warm due to the frequency of access
if err := sto.Burner().Burn(params.WarmStorageReadCostEIP2929); err != nil {
return &StylusParams{}, err
}

// paid for the read above
word := sto.GetFree(common.Hash{})
data := word[:]
take := func(count int) []byte {
value := data[:count]
data = data[count:]
return value
}

return &StylusParams{
backingStorage: sto,
Version: am.BytesToUint16(take(2)),
InkPrice: am.BytesToUint24(take(3)),
MaxStackDepth: am.BytesToUint32(take(4)),
FreePages: am.BytesToUint16(take(2)),
PageGas: am.BytesToUint16(take(2)),
PageRamp: am.BytesToUint(take(8)),
PageLimit: am.BytesToUint16(take(2)),
MinInitGas: am.BytesToUint16(take(2)),
ExpiryDays: am.BytesToUint16(take(2)),
KeepaliveDays: am.BytesToUint16(take(2)),
InitTableBits: am.BytesToUint8(take(1)),
TrieTableBits: am.BytesToUint8(take(1)),
}, nil
}

// Writes the params to permanent storage.
func (p *StylusParams) Save() error {
if p.backingStorage == nil {
log.Error("tried to Save invalid StylusParams")
return errors.New("invalid StylusParams")
}

data := am.ConcatByteSlices(
am.Uint16ToBytes(p.Version),
am.Uint24ToBytes(p.InkPrice),
am.Uint32ToBytes(p.MaxStackDepth),
am.Uint16ToBytes(p.FreePages),
am.Uint16ToBytes(p.PageGas),
am.UintToBytes(p.PageRamp),
am.Uint16ToBytes(p.PageLimit),
am.Uint16ToBytes(p.MinInitGas),
am.Uint16ToBytes(p.ExpiryDays),
am.Uint16ToBytes(p.KeepaliveDays),
am.Uint8ToBytes(p.InitTableBits),
am.Uint8ToBytes(p.TrieTableBits),
)
word := common.Hash{}
copy(word[:], data) // right-pad with zeros
return p.backingStorage.SetByUint64(0, word)
}

func initStylusParams(sto *storage.Storage) {
params := &StylusParams{
backingStorage: sto,
Version: 1,
InkPrice: initialInkPrice,
MaxStackDepth: initialStackDepth,
FreePages: InitialFreePages,
PageGas: InitialPageGas,
PageRamp: initialPageRamp,
PageLimit: initialPageLimit,
MinInitGas: initialMinInitGas,
ExpiryDays: initialExpiryDays,
KeepaliveDays: initialKeepaliveDays,
InitTableBits: initialInitTableBits,
TrieTableBits: initialTrieTableBits,
}
_ = params.Save()
}
Loading
Loading