Skip to content
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
14 changes: 8 additions & 6 deletions arbos/addressSet/addressSet.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ func (aset *AddressSet) GetAnyMember() (*common.Address, error) {
if err != nil || size == 0 {
return nil, err
}
addrAsHash, err := aset.backingStorage.GetByUint64(1)
addr := common.BytesToAddress(addrAsHash.Bytes())
return &addr, err
sba := aset.backingStorage.OpenStorageBackedAddressOrNil(1)
addr, err := sba.Get()
return addr, err
}

func (aset *AddressSet) Clear() error {
Expand All @@ -72,11 +72,11 @@ func (aset *AddressSet) AllMembers() ([]common.Address, error) {
}
ret := make([]common.Address, size)
for i := range ret {
bytes, err := aset.backingStorage.GetByUint64(uint64(i + 1))
sba := aset.backingStorage.OpenStorageBackedAddress(uint64(i + 1))
ret[i], err = sba.Get()
if err != nil {
return nil, err
}
ret[i] = common.BytesToAddress(bytes.Bytes())
}
return ret, nil
}
Expand All @@ -90,13 +90,15 @@ func (aset *AddressSet) Add(addr common.Address) error {
if err != nil {
return err
}
sba := aset.backingStorage.OpenStorageBackedAddress(1 + size)
slot := util.UintToHash(1 + size)
addrAsHash := common.BytesToHash(addr.Bytes())
err = aset.byAddress.Set(addrAsHash, slot)
if err != nil {
return err
}
err = aset.backingStorage.Set(slot, addrAsHash)
sba = aset.backingStorage.OpenStorageBackedAddress(1 + size)
err = sba.Set(addr)
if err != nil {
return err
}
Expand Down
10 changes: 8 additions & 2 deletions arbos/incomingmessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,11 @@ func parseBatchPostingReportMessage(rd io.Reader, chainId *big.Int, batchFetcher
if err != nil {
return nil, err
}
batchPosterAddr, err := util.AddressFrom256FromReader(rd)
batchPosterAddr, err := util.AddressFromReader(rd)
if err != nil {
return nil, err
}
_, err = util.HashFromReader(rd) // unused: data hash
if err != nil {
return nil, err
}
Expand All @@ -534,7 +538,9 @@ func parseBatchPostingReportMessage(rd io.Reader, chainId *big.Int, batchFetcher
batchDataGas += params.TxDataNonZeroGasEIP2028
}
}
data, err := util.PackInternalTxDataBatchPostingReport(batchTimestamp, batchPosterAddr, batchNum, batchDataGas, l1BaseFee.Big())
data, err := util.PackInternalTxDataBatchPostingReport(
batchTimestamp.Big(), batchPosterAddr, batchNum, batchDataGas, l1BaseFee.Big(),
)
if err != nil {
return nil, err
}
Expand Down
1 change: 0 additions & 1 deletion arbos/internal_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ func ApplyInternalTxUpdate(tx *types.ArbitrumInternalTx, state *arbosState.Arbos
_ = state.RetryableState().TryToReapOneRetryable(currentTime, evm, util.TracingDuringEVM)

state.L2PricingState().UpdatePricingModel(l2BaseFee, timePassed, state.FormatVersion(), false)
state.L1PricingState().UpdateTime(currentTime)

state.UpgradeArbosVersionIfNecessary(currentTime, evm.ChainConfig())
case InternalTxBatchPostingReportMethodID:
Expand Down
10 changes: 5 additions & 5 deletions arbos/l1pricing/batchPoster.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ package l1pricing

import (
"errors"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/offchainlabs/nitro/arbos/addressSet"
"github.com/offchainlabs/nitro/arbos/storage"
"github.com/offchainlabs/nitro/util/arbmath"
"math/big"
)

var (
PosterAddrsKey = []byte{0}
PosterInfoKey = []byte{1}

ErrNotExist = errors.New("batch poster does not exist in table")
ErrAlreadyExists = errors.New("tried to add a batch poster that already exists")
)

Expand Down Expand Up @@ -49,7 +49,7 @@ func (bpt *BatchPostersTable) OpenPoster(poster common.Address) (*BatchPosterSta
return nil, err
}
if !isBatchPoster {
return nil, ErrNotExist
return bpt.AddPoster(poster, poster)
}
return bpt.internalOpen(poster), nil
}
Expand All @@ -75,7 +75,7 @@ func (bpt *BatchPostersTable) AddPoster(posterAddress common.Address, payTo comm
return nil, ErrAlreadyExists
}
bpState := bpt.internalOpen(posterAddress)
if err := bpState.fundsDue.Set(big.NewInt(0)); err != nil {
if err := bpState.fundsDue.Set(common.Big0); err != nil {
return nil, err
}
if err := bpState.payTo.Set(payTo); err != nil {
Expand All @@ -98,7 +98,7 @@ func (bpt *BatchPostersTable) TotalFundsDue() (*big.Int, error) {
if err != nil {
return nil, err
}
ret := big.NewInt(0)
ret := common.Big0
for _, posterAddr := range allPosters {
poster, err := bpt.OpenPoster(posterAddr)
if err != nil {
Expand Down
104 changes: 51 additions & 53 deletions arbos/l1pricing/l1pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ type L1PricingState struct {
storage *storage.Storage

// parameters
batchPosterTable *BatchPostersTable
payRewardsTo storage.StorageBackedAddress
equilibrationTime storage.StorageBackedUint64
inertia storage.StorageBackedUint64
perUnitReward storage.StorageBackedUint64
batchPosterTable *BatchPostersTable
payRewardsTo storage.StorageBackedAddress
equilibrationUnits storage.StorageBackedBigInt
inertia storage.StorageBackedUint64
perUnitReward storage.StorageBackedUint64
// variables
currentTime storage.StorageBackedUint64
lastUpdateTime storage.StorageBackedUint64 // timestamp of the last update from L1 that we processed
fundsDueForRewards storage.StorageBackedBigInt
// funds collected since update are recorded as the balance in account L1PricerFundsPoolAddress
Expand All @@ -50,21 +49,20 @@ var (

const (
payRewardsToOffset uint64 = iota
equilibrationTimeOffset
equilibrationUnitsOffset
inertiaOffset
perUnitRewardOffset
currentTimeOffset
lastUpdateTimeOffset
fundsDueForRewards
fundsDueForRewardsOffset
unitsSinceOffset
pricePerUnitOffset
)

const (
InitialEquilibrationTime = 60 * 60 // one hour
InitialInertia = 10
InitialPerUnitReward = 10
InitialPricePerUnitWei = 50 * params.GWei
InitialEquilibrationUnits uint64 = 60 * params.TxDataNonZeroGasEIP2028 * 100000 // one minute at 100000 bytes / sec
InitialInertia = 10
InitialPerUnitReward = 10
InitialPricePerUnitWei = 50 * params.GWei
)

func InitializeL1PricingState(sto *storage.Storage) error {
Expand All @@ -79,12 +77,17 @@ func InitializeL1PricingState(sto *storage.Storage) error {
if err := sto.SetByUint64(payRewardsToOffset, util.AddressToHash(BatchPosterAddress)); err != nil {
return err
}
if err := sto.SetUint64ByUint64(equilibrationTimeOffset, InitialEquilibrationTime); err != nil {
equilibrationUnits := sto.OpenStorageBackedBigInt(equilibrationUnitsOffset)
if err := equilibrationUnits.Set(am.UintToBig(InitialEquilibrationUnits)); err != nil {
return err
}
if err := sto.SetUint64ByUint64(inertiaOffset, InitialInertia); err != nil {
return err
}
fundsDueForRewards := sto.OpenStorageBackedBigInt(fundsDueForRewardsOffset)
if err := fundsDueForRewards.Set(common.Big0); err != nil {
return err
}
if err := sto.SetUint64ByUint64(perUnitRewardOffset, InitialPerUnitReward); err != nil {
return err
}
Expand All @@ -97,12 +100,11 @@ func OpenL1PricingState(sto *storage.Storage) *L1PricingState {
sto,
OpenBatchPostersTable(sto.OpenSubStorage(BatchPosterTableKey)),
sto.OpenStorageBackedAddress(payRewardsToOffset),
sto.OpenStorageBackedUint64(equilibrationTimeOffset),
sto.OpenStorageBackedBigInt(equilibrationUnitsOffset),
sto.OpenStorageBackedUint64(inertiaOffset),
sto.OpenStorageBackedUint64(perUnitRewardOffset),
sto.OpenStorageBackedUint64(currentTimeOffset),
sto.OpenStorageBackedUint64(lastUpdateTimeOffset),
sto.OpenStorageBackedBigInt(fundsDueForRewards),
sto.OpenStorageBackedBigInt(fundsDueForRewardsOffset),
sto.OpenStorageBackedUint64(unitsSinceOffset),
sto.OpenStorageBackedBigInt(pricePerUnitOffset),
}
Expand All @@ -120,12 +122,12 @@ func (ps *L1PricingState) SetPayRewardsTo(addr common.Address) error {
return ps.payRewardsTo.Set(addr)
}

func (ps *L1PricingState) EquilibrationTime() (uint64, error) {
return ps.equilibrationTime.Get()
func (ps *L1PricingState) EquilibrationUnits() (*big.Int, error) {
return ps.equilibrationUnits.Get()
}

func (ps *L1PricingState) SetEquilibrationTime(equilTime uint64) error {
return ps.equilibrationTime.Set(equilTime)
func (ps *L1PricingState) SetEquilibrationUnits(equilUnits *big.Int) error {
return ps.equilibrationUnits.Set(equilUnits)
}

func (ps *L1PricingState) Inertia() (uint64, error) {
Expand All @@ -144,14 +146,6 @@ func (ps *L1PricingState) SetPerUnitReward(weiPerUnit uint64) error {
return ps.perUnitReward.Set(weiPerUnit)
}

func (ps *L1PricingState) CurrentTime() (uint64, error) {
return ps.currentTime.Get()
}

func (ps *L1PricingState) SetCurrentTime(t uint64) error {
return ps.currentTime.Set(t)
}

func (ps *L1PricingState) LastUpdateTime() (uint64, error) {
return ps.lastUpdateTime.Get()
}
Expand Down Expand Up @@ -192,11 +186,6 @@ func (ps *L1PricingState) SetPricePerUnit(price *big.Int) error {
return ps.pricePerUnit.Set(price)
}

// Update the pricing model with info from the start of a block
func (ps *L1PricingState) UpdateTime(currentTime uint64) {
_ = ps.SetCurrentTime(currentTime)
}

// Update the pricing model based on a payment by a batch poster
func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *vm.EVM, updateTime uint64, currentTime uint64, batchPoster common.Address, weiSpent *big.Int) error {
batchPosterTable := ps.BatchPosterTable()
Expand All @@ -214,7 +203,7 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *
if err != nil {
return err
}
oldShortfall := am.BigSub(am.BigAdd(totalFundsDue, fundsDueForRewards), statedb.GetBalance(L1PricerFundsPoolAddress))
oldShortfall := am.BigSub(statedb.GetBalance(L1PricerFundsPoolAddress), am.BigAdd(totalFundsDue, fundsDueForRewards))

// compute allocation fraction -- will allocate updateTimeDelta/timeDelta fraction of units and funds to this update
lastUpdateTime, err := ps.LastUpdateTime()
Expand Down Expand Up @@ -267,7 +256,8 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *
if am.BigLessThan(availableFunds, paymentForRewards) {
paymentForRewards = availableFunds
}
if err := ps.SetFundsDueForRewards(am.BigSub(fundsDueForRewards, paymentForRewards)); err != nil {
fundsDueForRewards = am.BigSub(fundsDueForRewards, paymentForRewards)
if err := ps.SetFundsDueForRewards(fundsDueForRewards); err != nil {
return err
}
payRewardsTo, err := ps.PayRewardsTo()
Expand All @@ -285,7 +275,6 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *
if err != nil {
return err
}
remainingFundsDueToPosters := big.NewInt(0)
for _, posterAddr := range allPosterAddrs {
poster, err := batchPosterTable.OpenPoster(posterAddr)
if err != nil {
Expand Down Expand Up @@ -315,9 +304,6 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *
return err
}
}
if balanceDueToPoster.Sign() > 0 {
remainingFundsDueToPosters = am.BigAdd(remainingFundsDueToPosters, balanceDueToPoster)
}
}

// update time
Expand All @@ -327,40 +313,52 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(statedb vm.StateDB, evm *

// adjust the price
if unitsAllocated > 0 {
shortfall := am.BigSub(am.BigAdd(remainingFundsDueToPosters, fundsDueForRewards), statedb.GetBalance(L1PricerFundsPoolAddress))
totalFundsDue, err = batchPosterTable.TotalFundsDue()
if err != nil {
return err
}
fundsDueForRewards, err = ps.FundsDueForRewards()
if err != nil {
return err
}
shortfall := am.BigSub(statedb.GetBalance(L1PricerFundsPoolAddress), am.BigAdd(totalFundsDue, fundsDueForRewards))

inertia, err := ps.Inertia()
if err != nil {
return err
}
equilTime, err := ps.EquilibrationTime()
equilUnits, err := ps.EquilibrationUnits()
if err != nil {
return err
}
inertiaUnits := am.BigDivByUint(equilUnits, inertia)
price, err := ps.PricePerUnit()
if err != nil {
return err
}

priceChange := am.BigDivByUint(
am.BigAdd(am.BigSub(shortfall, oldShortfall), am.BigDivByUint(shortfall, equilTime)),
unitsAllocated+equilTime/inertia,
allocPlusInert := am.BigAddByUint(inertiaUnits, unitsAllocated)
priceChange := am.BigDiv(
am.BigSub(
am.BigMul(shortfall, am.BigSub(equilUnits, common.Big1)),
am.BigMul(oldShortfall, equilUnits),
),
am.BigMul(equilUnits, allocPlusInert),
)

newPrice := am.BigSub(price, priceChange)
if newPrice.Sign() >= 0 {
price = newPrice
} else {
price = big.NewInt(0)
newPrice := am.BigAdd(price, priceChange)
if newPrice.Sign() < 0 {
newPrice = common.Big0
}
if err := ps.SetPricePerUnit(price); err != nil {
if err := ps.SetPricePerUnit(newPrice); err != nil {
return err
}
}
return nil
}

func (ps *L1PricingState) AddPosterInfo(tx *types.Transaction, posterAddr common.Address) {
tx.PosterCost = big.NewInt(0)
tx.PosterCost = common.Big0
tx.PosterIsReimbursable = false

contains, err := ps.batchPosterTable.ContainsPoster(posterAddr)
Expand Down Expand Up @@ -400,7 +398,7 @@ func (ps *L1PricingState) PosterDataCost(message core.Message, poster common.Add
byteCount, err := byteCountAfterBrotli0(message.Data())
if err != nil {
log.Error("failed to compress tx", "err", err)
return big.NewInt(0), 0, false
return common.Big0, 0, false
}

// Approximate the l1 fee charged for posting this tx's calldata
Expand Down
3 changes: 2 additions & 1 deletion arbos/l1pricing/l1pricing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package l1pricing

import (
am "github.com/offchainlabs/nitro/util/arbmath"
"math"
"math/big"
"testing"
Expand Down Expand Up @@ -61,7 +62,7 @@ func TestL1PriceUpdate(t *testing.T) {
Fail(t)
}

initialPriceEstimate := big.NewInt(InitialPricePerUnitWei)
initialPriceEstimate := am.UintToBig(InitialPricePerUnitWei)
priceEstimate, err := ps.PricePerUnit()
Require(t, err)
if priceEstimate.Cmp(initialPriceEstimate) != 0 {
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/precompiles/ArbOwner.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ interface ArbOwner {
/// @notice Upgrades ArbOS to the requested version at the requested timestamp
function scheduleArbOSUpgrade(uint64 newVersion, uint64 timestamp) external;

/// @notice Sets equilibration time parameter for L1 price adjustment algorithm
function setL1PricingEquilibrationTime(uint64 equilibrationTime) external;
/// @notice Sets equilibration units parameter for L1 price adjustment algorithm
function setL1PricingEquilibrationUnits(uint256 equilibrationUnits) external;

/// @notice Sets inertia parameter for L1 price adjustment algorithm
function setL1PricingInertia(uint64 inertia) external;
Expand Down
Loading