Skip to content

Commit

Permalink
cache last N
Browse files Browse the repository at this point in the history
  • Loading branch information
rachel-bousfield committed Apr 9, 2024
1 parent 63551f9 commit f057a89
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
32 changes: 32 additions & 0 deletions arbos/programs/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE

package programs

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

type RecentPrograms struct {
queue []common.Hash
items map[common.Hash]struct{}
}

func NewRecentProgramsTracker() *RecentPrograms {
return &RecentPrograms{
queue: make([]common.Hash, 0, initialTxCacheSize),
items: make(map[common.Hash]struct{}, initialTxCacheSize),
}
}

func (p *RecentPrograms) Insert(item common.Hash, params *StylusParams) bool {
if _, ok := p.items[item]; ok {
return true
}
p.queue = append(p.queue, item)
p.items[item] = struct{}{}

if len(p.queue) > int(params.TxCacheSize) {
p.queue = p.queue[1:]
delete(p.items, item)
}
return false
}
5 changes: 5 additions & 0 deletions arbos/programs/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const initialMinInitGas = 0 // assume pricer is correct (update in case
const initialMinCachedInitGas = 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 initialTxCacheSize = 16 // cache the 16 most recent programs

// 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).
Expand All @@ -41,6 +42,7 @@ type StylusParams struct {
MinCachedInitGas uint8 // measured in 64-gas increments
ExpiryDays uint16
KeepaliveDays uint16
TxCacheSize uint8
}

// Provides a view of the Stylus parameters. Call Save() to persist.
Expand Down Expand Up @@ -81,6 +83,7 @@ func (p Programs) Params() (*StylusParams, error) {
MinCachedInitGas: am.BytesToUint8(take(1)),
ExpiryDays: am.BytesToUint16(take(2)),
KeepaliveDays: am.BytesToUint16(take(2)),
TxCacheSize: am.BytesToUint8(take(1)),
}, nil
}

Expand All @@ -104,6 +107,7 @@ func (p *StylusParams) Save() error {
am.Uint8ToBytes(p.MinCachedInitGas),
am.Uint16ToBytes(p.ExpiryDays),
am.Uint16ToBytes(p.KeepaliveDays),
am.Uint8ToBytes(p.TxCacheSize),
)

slot := uint64(0)
Expand Down Expand Up @@ -136,6 +140,7 @@ func initStylusParams(sto *storage.Storage) {
MinCachedInitGas: initialMinCachedInitGas,
ExpiryDays: initialExpiryDays,
KeepaliveDays: initialKeepaliveDays,
TxCacheSize: initialTxCacheSize,
}
_ = params.Save()
}
9 changes: 6 additions & 3 deletions arbos/programs/programs.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,22 +150,24 @@ func (p Programs) CallProgram(
interpreter *vm.EVMInterpreter,
tracingInfo *util.TracingInfo,
calldata []byte,
recentPrograms *RecentPrograms,
reentrant bool,
) ([]byte, error) {
evm := interpreter.Evm()
contract := scope.Contract
codeHash := contract.CodeHash
debugMode := evm.ChainConfig().DebugMode()

params, err := p.Params()
if err != nil {
return nil, err
}

program, err := p.getActiveProgram(contract.CodeHash, evm.Context.Time, params)
program, err := p.getActiveProgram(codeHash, evm.Context.Time, params)
if err != nil {
return nil, err
}
moduleHash, err := p.moduleHashes.Get(contract.CodeHash)
moduleHash, err := p.moduleHashes.Get(codeHash)
if err != nil {
return nil, err
}
Expand All @@ -181,7 +183,8 @@ func (p Programs) CallProgram(
callCost := model.GasCost(program.footprint, open, ever)

// pay for program init
if program.cached {
cached := program.cached || recentPrograms.Insert(codeHash, params)
if cached {
callCost = arbmath.SaturatingUAdd(callCost, 64*uint64(params.MinCachedInitGas))
callCost = arbmath.SaturatingUAdd(callCost, uint64(program.cachedInitGas))
} else {
Expand Down
8 changes: 6 additions & 2 deletions arbos/tx_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"math/big"

"github.com/offchainlabs/nitro/arbos/l1pricing"
"github.com/offchainlabs/nitro/arbos/programs"

"github.com/offchainlabs/nitro/arbos/util"
"github.com/offchainlabs/nitro/util/arbmath"
Expand Down Expand Up @@ -41,8 +42,9 @@ type TxProcessor struct {
computeHoldGas uint64 // amount of gas temporarily held to prevent compute from exceeding the gas limit
delayedInbox bool // whether this tx was submitted through the delayed inbox
Contracts []*vm.Contract
Programs map[common.Address]uint // # of distinct context spans for each program
TopTxType *byte // set once in StartTxHook
Programs map[common.Address]uint // # of distinct context spans for each program
RecentPrograms *programs.RecentPrograms // programs recently accessed this tx
TopTxType *byte // set once in StartTxHook
evm *vm.EVM
CurrentRetryable *common.Hash
CurrentRefundTo *common.Address
Expand All @@ -64,6 +66,7 @@ func NewTxProcessor(evm *vm.EVM, msg *core.Message) *TxProcessor {
delayedInbox: evm.Context.Coinbase != l1pricing.BatchPosterAddress,
Contracts: []*vm.Contract{},
Programs: make(map[common.Address]uint),
RecentPrograms: programs.NewRecentProgramsTracker(),
TopTxType: nil,
evm: evm,
CurrentRetryable: nil,
Expand Down Expand Up @@ -125,6 +128,7 @@ func (p *TxProcessor) ExecuteWASM(scope *vm.ScopeContext, input []byte, interpre
interpreter,
tracingInfo,
input,
p.RecentPrograms,
reentrant,
)
}
Expand Down
2 changes: 1 addition & 1 deletion contracts

0 comments on commit f057a89

Please sign in to comment.