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

Cache storage keys #1767

Merged
merged 19 commits into from
Oct 24, 2023
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
92 changes: 47 additions & 45 deletions arbos/addressSet/addressSet.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package addressSet

// TODO lowercase this package name

import (
"errors"

Expand All @@ -26,49 +28,49 @@ func Initialize(sto *storage.Storage) error {

func OpenAddressSet(sto *storage.Storage) *AddressSet {
magicxyyz marked this conversation as resolved.
Show resolved Hide resolved
return &AddressSet{
sto,
sto.OpenStorageBackedUint64(0),
sto.OpenSubStorage([]byte{0}),
backingStorage: sto.WithoutCache(),
size: sto.OpenStorageBackedUint64(0),
byAddress: sto.OpenSubStorage([]byte{0}),
}
}

magicxyyz marked this conversation as resolved.
Show resolved Hide resolved
func (aset *AddressSet) Size() (uint64, error) {
return aset.size.Get()
func (as *AddressSet) Size() (uint64, error) {
return as.size.Get()
}

func (aset *AddressSet) IsMember(addr common.Address) (bool, error) {
value, err := aset.byAddress.Get(util.AddressToHash(addr))
func (as *AddressSet) IsMember(addr common.Address) (bool, error) {
value, err := as.byAddress.Get(util.AddressToHash(addr))
return value != (common.Hash{}), err
}

func (aset *AddressSet) GetAnyMember() (*common.Address, error) {
size, err := aset.size.Get()
func (as *AddressSet) GetAnyMember() (*common.Address, error) {
size, err := as.size.Get()
if err != nil || size == 0 {
return nil, err
}
sba := aset.backingStorage.OpenStorageBackedAddressOrNil(1)
sba := as.backingStorage.OpenStorageBackedAddressOrNil(1)
addr, err := sba.Get()
return addr, err
}

func (aset *AddressSet) Clear() error {
size, err := aset.size.Get()
func (as *AddressSet) Clear() error {
size, err := as.size.Get()
if err != nil || size == 0 {
return err
}
for i := uint64(1); i <= size; i++ {
contents, _ := aset.backingStorage.GetByUint64(i)
_ = aset.backingStorage.ClearByUint64(i)
err = aset.byAddress.Clear(contents)
contents, _ := as.backingStorage.GetByUint64(i)
_ = as.backingStorage.ClearByUint64(i)
err = as.byAddress.Clear(contents)
if err != nil {
return err
}
}
return aset.size.Clear()
return as.size.Clear()
}

func (aset *AddressSet) AllMembers(maxNumToReturn uint64) ([]common.Address, error) {
size, err := aset.size.Get()
func (as *AddressSet) AllMembers(maxNumToReturn uint64) ([]common.Address, error) {
size, err := as.size.Get()
if err != nil {
return nil, err
}
Expand All @@ -77,7 +79,7 @@ func (aset *AddressSet) AllMembers(maxNumToReturn uint64) ([]common.Address, err
}
ret := make([]common.Address, size)
for i := range ret {
sba := aset.backingStorage.OpenStorageBackedAddress(uint64(i + 1))
sba := as.backingStorage.OpenStorageBackedAddress(uint64(i + 1))
ret[i], err = sba.Get()
if err != nil {
return nil, err
Expand All @@ -86,38 +88,38 @@ func (aset *AddressSet) AllMembers(maxNumToReturn uint64) ([]common.Address, err
return ret, nil
}

func (aset *AddressSet) ClearList() error {
size, err := aset.size.Get()
func (as *AddressSet) ClearList() error {
size, err := as.size.Get()
if err != nil || size == 0 {
return err
}
for i := uint64(1); i <= size; i++ {
err = aset.backingStorage.ClearByUint64(i)
err = as.backingStorage.ClearByUint64(i)
if err != nil {
return err
}
}
return aset.size.Clear()
return as.size.Clear()
}

func (aset *AddressSet) RectifyMapping(addr common.Address) error {
isOwner, err := aset.IsMember(addr)
func (as *AddressSet) RectifyMapping(addr common.Address) error {
isOwner, err := as.IsMember(addr)
if !isOwner || err != nil {
return errors.New("RectifyMapping: Address is not an owner")
}

// If the mapping is correct, RectifyMapping shouldn't do anything
// Additional safety check to avoid corruption of mapping after the initial fix
addrAsHash := common.BytesToHash(addr.Bytes())
slot, err := aset.byAddress.GetUint64(addrAsHash)
slot, err := as.byAddress.GetUint64(addrAsHash)
if err != nil {
return err
}
atSlot, err := aset.backingStorage.GetByUint64(slot)
atSlot, err := as.backingStorage.GetByUint64(slot)
if err != nil {
return err
}
size, err := aset.size.Get()
size, err := as.size.Get()
if err != nil {
return err
}
Expand All @@ -126,72 +128,72 @@ func (aset *AddressSet) RectifyMapping(addr common.Address) error {
}

// Remove the owner from map and add them as a new owner
err = aset.byAddress.Clear(addrAsHash)
err = as.byAddress.Clear(addrAsHash)
if err != nil {
return err
}

return aset.Add(addr)
return as.Add(addr)
}

func (aset *AddressSet) Add(addr common.Address) error {
present, err := aset.IsMember(addr)
func (as *AddressSet) Add(addr common.Address) error {
present, err := as.IsMember(addr)
if present || err != nil {
return err
}
size, err := aset.size.Get()
size, err := as.size.Get()
if err != nil {
return err
}
slot := util.UintToHash(1 + size)
addrAsHash := common.BytesToHash(addr.Bytes())
err = aset.byAddress.Set(addrAsHash, slot)
err = as.byAddress.Set(addrAsHash, slot)
if err != nil {
return err
}
sba := aset.backingStorage.OpenStorageBackedAddress(1 + size)
sba := as.backingStorage.OpenStorageBackedAddress(1 + size)
err = sba.Set(addr)
if err != nil {
return err
}
_, err = aset.size.Increment()
_, err = as.size.Increment()
return err
}

func (aset *AddressSet) Remove(addr common.Address, arbosVersion uint64) error {
func (as *AddressSet) Remove(addr common.Address, arbosVersion uint64) error {
addrAsHash := common.BytesToHash(addr.Bytes())
slot, err := aset.byAddress.GetUint64(addrAsHash)
slot, err := as.byAddress.GetUint64(addrAsHash)
if slot == 0 || err != nil {
return err
}
err = aset.byAddress.Clear(addrAsHash)
err = as.byAddress.Clear(addrAsHash)
if err != nil {
return err
}
size, err := aset.size.Get()
size, err := as.size.Get()
if err != nil {
return err
}
if slot < size {
atSize, err := aset.backingStorage.GetByUint64(size)
atSize, err := as.backingStorage.GetByUint64(size)
if err != nil {
return err
}
err = aset.backingStorage.SetByUint64(slot, atSize)
err = as.backingStorage.SetByUint64(slot, atSize)
if err != nil {
return err
}
if arbosVersion >= 11 {
err = aset.byAddress.Set(atSize, util.UintToHash(slot))
err = as.byAddress.Set(atSize, util.UintToHash(slot))
if err != nil {
return err
}
}
}
err = aset.backingStorage.ClearByUint64(size)
err = as.backingStorage.ClearByUint64(size)
if err != nil {
return err
}
_, err = aset.size.Decrement()
_, err = as.size.Decrement()
return err
}
4 changes: 3 additions & 1 deletion arbos/addressTable/addressTable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package addressTable

// TODO lowercase this package name

import (
"bytes"
"errors"
Expand All @@ -25,7 +27,7 @@ func Initialize(sto *storage.Storage) {

magicxyyz marked this conversation as resolved.
Show resolved Hide resolved
func Open(sto *storage.Storage) *AddressTable {
numItems := sto.OpenStorageBackedUint64(0)
return &AddressTable{sto, sto.OpenSubStorage([]byte{}), numItems}
return &AddressTable{sto.WithoutCache(), sto.OpenSubStorage([]byte{}), numItems}
}

func (atab *AddressTable) Register(addr common.Address) (uint64, error) {
Expand Down
32 changes: 16 additions & 16 deletions arbos/arbosState/arbosstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ func OpenArbosState(stateDB vm.StateDB, burner burn.Burner) (*ArbosState, error)
backingStorage.OpenStorageBackedUint64(uint64(upgradeVersionOffset)),
backingStorage.OpenStorageBackedUint64(uint64(upgradeTimestampOffset)),
backingStorage.OpenStorageBackedAddress(uint64(networkFeeAccountOffset)),
l1pricing.OpenL1PricingState(backingStorage.OpenSubStorage(l1PricingSubspace)),
l2pricing.OpenL2PricingState(backingStorage.OpenSubStorage(l2PricingSubspace)),
retryables.OpenRetryableState(backingStorage.OpenSubStorage(retryablesSubspace), stateDB),
addressTable.Open(backingStorage.OpenSubStorage(addressTableSubspace)),
addressSet.OpenAddressSet(backingStorage.OpenSubStorage(chainOwnerSubspace)),
merkleAccumulator.OpenMerkleAccumulator(backingStorage.OpenSubStorage(sendMerkleSubspace)),
blockhash.OpenBlockhashes(backingStorage.OpenSubStorage(blockhashesSubspace)),
l1pricing.OpenL1PricingState(backingStorage.OpenCachedSubStorage(l1PricingSubspace)),
l2pricing.OpenL2PricingState(backingStorage.OpenCachedSubStorage(l2PricingSubspace)),
retryables.OpenRetryableState(backingStorage.OpenCachedSubStorage(retryablesSubspace), stateDB),
addressTable.Open(backingStorage.OpenCachedSubStorage(addressTableSubspace)),
addressSet.OpenAddressSet(backingStorage.OpenCachedSubStorage(chainOwnerSubspace)),
merkleAccumulator.OpenMerkleAccumulator(backingStorage.OpenCachedSubStorage(sendMerkleSubspace)),
blockhash.OpenBlockhashes(backingStorage.OpenCachedSubStorage(blockhashesSubspace)),
backingStorage.OpenStorageBackedBigInt(uint64(chainIdOffset)),
backingStorage.OpenStorageBackedBytes(chainConfigSubspace),
backingStorage.OpenStorageBackedUint64(uint64(genesisBlockNumOffset)),
Expand Down Expand Up @@ -225,14 +225,14 @@ func InitializeArbosState(stateDB vm.StateDB, burner burn.Burner, chainConfig *p
if desiredArbosVersion >= 2 {
initialRewardsRecipient = initialChainOwner
}
_ = l1pricing.InitializeL1PricingState(sto.OpenSubStorage(l1PricingSubspace), initialRewardsRecipient, initMessage.InitialL1BaseFee)
_ = l2pricing.InitializeL2PricingState(sto.OpenSubStorage(l2PricingSubspace))
_ = retryables.InitializeRetryableState(sto.OpenSubStorage(retryablesSubspace))
addressTable.Initialize(sto.OpenSubStorage(addressTableSubspace))
merkleAccumulator.InitializeMerkleAccumulator(sto.OpenSubStorage(sendMerkleSubspace))
blockhash.InitializeBlockhashes(sto.OpenSubStorage(blockhashesSubspace))

ownersStorage := sto.OpenSubStorage(chainOwnerSubspace)
_ = l1pricing.InitializeL1PricingState(sto.OpenCachedSubStorage(l1PricingSubspace), initialRewardsRecipient, initMessage.InitialL1BaseFee)
_ = l2pricing.InitializeL2PricingState(sto.OpenCachedSubStorage(l2PricingSubspace))
_ = retryables.InitializeRetryableState(sto.OpenCachedSubStorage(retryablesSubspace))
addressTable.Initialize(sto.OpenCachedSubStorage(addressTableSubspace))
merkleAccumulator.InitializeMerkleAccumulator(sto.OpenCachedSubStorage(sendMerkleSubspace))
blockhash.InitializeBlockhashes(sto.OpenCachedSubStorage(blockhashesSubspace))

ownersStorage := sto.OpenCachedSubStorage(chainOwnerSubspace)
_ = addressSet.Initialize(ownersStorage)
_ = addressSet.OpenAddressSet(ownersStorage).Add(initialChainOwner)

Expand Down Expand Up @@ -428,7 +428,7 @@ func (state *ArbosState) ChainOwners() *addressSet.AddressSet {

func (state *ArbosState) SendMerkleAccumulator() *merkleAccumulator.MerkleAccumulator {
if state.sendMerkle == nil {
state.sendMerkle = merkleAccumulator.OpenMerkleAccumulator(state.backingStorage.OpenSubStorage(sendMerkleSubspace))
state.sendMerkle = merkleAccumulator.OpenMerkleAccumulator(state.backingStorage.OpenCachedSubStorage(sendMerkleSubspace))
}
return state.sendMerkle
}
Expand Down
2 changes: 1 addition & 1 deletion arbos/arbosState/arbosstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestStorageBackedInt64(t *testing.T) {

func TestStorageSlots(t *testing.T) {
state, _ := NewArbosMemoryBackedArbOSState()
sto := state.BackingStorage().OpenSubStorage([]byte{})
sto := state.BackingStorage().OpenCachedSubStorage([]byte{})

println("nil address", colors.Blue, storage.NilAddressRepresentation.String(), colors.Clear)

Expand Down
2 changes: 1 addition & 1 deletion arbos/blockhash/blockhash.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func InitializeBlockhashes(backingStorage *storage.Storage) {
}

func OpenBlockhashes(backingStorage *storage.Storage) *Blockhashes {
return &Blockhashes{backingStorage, backingStorage.OpenStorageBackedUint64(0)}
return &Blockhashes{backingStorage.WithoutCache(), backingStorage.OpenStorageBackedUint64(0)}
}

func (bh *Blockhashes) L1BlockNumber() (uint64, error) {
Expand Down
4 changes: 2 additions & 2 deletions arbos/l1pricing/batchPoster.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ func InitializeBatchPostersTable(storage *storage.Storage) error {
if err := totalFundsDue.SetChecked(common.Big0); err != nil {
return err
}
return addressSet.Initialize(storage.OpenSubStorage(PosterAddrsKey))
return addressSet.Initialize(storage.OpenCachedSubStorage(PosterAddrsKey))
}

func OpenBatchPostersTable(storage *storage.Storage) *BatchPostersTable {
return &BatchPostersTable{
posterAddrs: addressSet.OpenAddressSet(storage.OpenSubStorage(PosterAddrsKey)),
posterAddrs: addressSet.OpenAddressSet(storage.OpenCachedSubStorage(PosterAddrsKey)),
posterInfo: storage.OpenSubStorage(PosterInfoKey),
totalFundsDue: storage.OpenStorageBackedBigInt(totalFundsDueOffset),
}
Expand Down
4 changes: 2 additions & 2 deletions arbos/l1pricing/l1pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ var InitialEquilibrationUnitsV0 = arbmath.UintToBig(60 * params.TxDataNonZeroGas
var InitialEquilibrationUnitsV6 = arbmath.UintToBig(params.TxDataNonZeroGasEIP2028 * 10000000)

func InitializeL1PricingState(sto *storage.Storage, initialRewardsRecipient common.Address, initialL1BaseFee *big.Int) error {
bptStorage := sto.OpenSubStorage(BatchPosterTableKey)
bptStorage := sto.OpenCachedSubStorage(BatchPosterTableKey)
if err := InitializeBatchPostersTable(bptStorage); err != nil {
return err
}
Expand Down Expand Up @@ -118,7 +118,7 @@ func InitializeL1PricingState(sto *storage.Storage, initialRewardsRecipient comm
func OpenL1PricingState(sto *storage.Storage) *L1PricingState {
return &L1PricingState{
sto,
OpenBatchPostersTable(sto.OpenSubStorage(BatchPosterTableKey)),
OpenBatchPostersTable(sto.OpenCachedSubStorage(BatchPosterTableKey)),
sto.OpenStorageBackedAddress(payRewardsToOffset),
sto.OpenStorageBackedBigUint(equilibrationUnitsOffset),
sto.OpenStorageBackedUint64(inertiaOffset),
Expand Down
2 changes: 1 addition & 1 deletion arbos/queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func TestQueue(t *testing.T) {
state, statedb := arbosState.NewArbosMemoryBackedArbOSState()
sto := state.BackingStorage().OpenSubStorage([]byte{})
sto := state.BackingStorage().OpenCachedSubStorage([]byte{})
Require(t, storage.InitializeQueue(sto))
q := storage.OpenQueue(sto)

Expand Down
5 changes: 3 additions & 2 deletions arbos/retryables/retryable.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ var (
)

func InitializeRetryableState(sto *storage.Storage) error {
return storage.InitializeQueue(sto.OpenSubStorage(timeoutQueueKey))
return storage.InitializeQueue(sto.OpenCachedSubStorage(timeoutQueueKey))
}

func OpenRetryableState(sto *storage.Storage, statedb vm.StateDB) *RetryableState {
return &RetryableState{
sto,
storage.OpenQueue(sto.OpenSubStorage(timeoutQueueKey)),
storage.OpenQueue(sto.OpenCachedSubStorage(timeoutQueueKey)),
}
}

Expand Down Expand Up @@ -150,6 +150,7 @@ func (rs *RetryableState) DeleteRetryable(id common.Hash, evm *vm.EVM, scenario
return false, err
}

// we ignore returned error as we expect that if one ClearByUint64 fails, than all consecutive calls to ClearByUint64 will fail with the same error (not modifying state), and then ClearBytes will also fail with the same error (also not modifying state) - and this one we check and return
_ = retStorage.ClearByUint64(numTriesOffset)
_ = retStorage.ClearByUint64(fromOffset)
_ = retStorage.ClearByUint64(toOffset)
Expand Down
2 changes: 1 addition & 1 deletion arbos/storage/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func InitializeQueue(sto *Storage) error {

func OpenQueue(sto *Storage) *Queue {
return &Queue{
sto,
sto.WithoutCache(),
sto.OpenStorageBackedUint64(0),
sto.OpenStorageBackedUint64(1),
}
Expand Down
Loading
Loading