Skip to content

Commit

Permalink
address PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ganeshvanahalli committed Sep 28, 2023
1 parent 01ee1f3 commit 291f889
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 70 deletions.
2 changes: 1 addition & 1 deletion arbcompress/compress_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ func compressedBufferSizeFor(length int) int {
return length + (length>>10)*8 + 64 // actual limit is: length + (length >> 14) * 4 + 6
}

func CompressFast(input []byte, level int) ([]byte, error) {
func CompressLevel(input []byte, level int) ([]byte, error) {
return compressLevel(input, level)
}
2 changes: 1 addition & 1 deletion arbcompress/compress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func testCompressDecompress(t *testing.T, data []byte) {
}
testDecompress(t, compressedWell, data)

compressedFast, err := CompressFast(data, 0)
compressedFast, err := CompressLevel(data, 0)
if err != nil {
t.Fatal(err)
}
Expand Down
3 changes: 1 addition & 2 deletions arbitrator/prover/test-cases/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
merkletree "github.com/wealdtech/go-merkletree"

"github.com/offchainlabs/nitro/arbcompress"
"github.com/offchainlabs/nitro/arbos/l1pricing"
)

// MerkleSample is an example using the Merkle tree to generate and verify proofs.
Expand Down Expand Up @@ -43,7 +42,7 @@ func MerkleSample(data [][]byte, toproove int) (bool, error) {
}

func testCompression(data []byte) {
compressed, err := arbcompress.CompressFast(data, l1pricing.InitialBrotliCompressionLevel)
compressed, err := arbcompress.CompressLevel(data, 0)
if err != nil {
panic(err)
}
Expand Down
6 changes: 5 additions & 1 deletion arbnode/execution/tx_pre_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ func PreCheckTx(bc *core.BlockChain, chainConfig *params.ChainConfig, header *ty
if config.Strictness >= TxPreCheckerStrictnessFullValidation && tx.Nonce() > stateNonce {
return MakeNonceError(sender, tx.Nonce(), stateNonce)
}
dataCost, _ := arbos.L1PricingState().GetPosterInfo(tx, l1pricing.BatchPosterAddress)
brotliCompressionLevel, err := arbos.BrotliCompressionLevel()
if err != nil {
return fmt.Errorf("failed to get brotliCompressionLevel: %w", err)
}
dataCost, _ := arbos.L1PricingState().GetPosterInfo(tx, l1pricing.BatchPosterAddress, brotliCompressionLevel)
dataGas := arbmath.BigDiv(dataCost, header.BaseFee)
if tx.Gas() < intrinsic+dataGas.Uint64() {
return core.ErrIntrinsicGas
Expand Down
52 changes: 34 additions & 18 deletions arbos/arbosState/arbosstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"

"github.com/offchainlabs/nitro/arbcompress"
"github.com/offchainlabs/nitro/arbos/addressSet"
"github.com/offchainlabs/nitro/arbos/addressTable"
"github.com/offchainlabs/nitro/arbos/arbostypes"
Expand All @@ -35,23 +36,24 @@ import (
// persisted beyond the end of the test.)

type ArbosState struct {
arbosVersion uint64 // version of the ArbOS storage format and semantics
upgradeVersion storage.StorageBackedUint64 // version we're planning to upgrade to, or 0 if not planning to upgrade
upgradeTimestamp storage.StorageBackedUint64 // when to do the planned upgrade
networkFeeAccount storage.StorageBackedAddress
l1PricingState *l1pricing.L1PricingState
l2PricingState *l2pricing.L2PricingState
retryableState *retryables.RetryableState
addressTable *addressTable.AddressTable
chainOwners *addressSet.AddressSet
sendMerkle *merkleAccumulator.MerkleAccumulator
blockhashes *blockhash.Blockhashes
chainId storage.StorageBackedBigInt
chainConfig storage.StorageBackedBytes
genesisBlockNum storage.StorageBackedUint64
infraFeeAccount storage.StorageBackedAddress
backingStorage *storage.Storage
Burner burn.Burner
arbosVersion uint64 // version of the ArbOS storage format and semantics
upgradeVersion storage.StorageBackedUint64 // version we're planning to upgrade to, or 0 if not planning to upgrade
upgradeTimestamp storage.StorageBackedUint64 // when to do the planned upgrade
networkFeeAccount storage.StorageBackedAddress
l1PricingState *l1pricing.L1PricingState
l2PricingState *l2pricing.L2PricingState
retryableState *retryables.RetryableState
addressTable *addressTable.AddressTable
chainOwners *addressSet.AddressSet
sendMerkle *merkleAccumulator.MerkleAccumulator
blockhashes *blockhash.Blockhashes
chainId storage.StorageBackedBigInt
chainConfig storage.StorageBackedBytes
genesisBlockNum storage.StorageBackedUint64
infraFeeAccount storage.StorageBackedAddress
brotliCompressionLevel storage.StorageBackedUint64 // brotli compression level used for pricing
backingStorage *storage.Storage
Burner burn.Burner
}

var ErrUninitializedArbOS = errors.New("ArbOS uninitialized")
Expand Down Expand Up @@ -82,6 +84,7 @@ func OpenArbosState(stateDB vm.StateDB, burner burn.Burner) (*ArbosState, error)
backingStorage.OpenStorageBackedBytes(chainConfigSubspace),
backingStorage.OpenStorageBackedUint64(uint64(genesisBlockNumOffset)),
backingStorage.OpenStorageBackedAddress(uint64(infraFeeAccountOffset)),
backingStorage.OpenStorageBackedUint64(uint64(brotliCompressionLevelOffset)),
backingStorage,
burner,
}, nil
Expand Down Expand Up @@ -139,6 +142,7 @@ const (
chainIdOffset
genesisBlockNumOffset
infraFeeAccountOffset
brotliCompressionLevelOffset
)

type SubspaceID []byte
Expand Down Expand Up @@ -215,6 +219,7 @@ func InitializeArbosState(stateDB vm.StateDB, burner burn.Burner, chainConfig *p
chainConfigStorage := sto.OpenStorageBackedBytes(chainConfigSubspace)
_ = chainConfigStorage.Set(initMessage.SerializedChainConfig)
_ = sto.SetUint64ByUint64(uint64(genesisBlockNumOffset), chainConfig.ArbitrumChainParams.GenesisBlockNum)
_ = sto.SetUint64ByUint64(uint64(brotliCompressionLevelOffset), 0) // default brotliCompressionLevel for fast compression is 0

initialRewardsRecipient := l1pricing.BatchPosterAddress
if desiredArbosVersion >= 2 {
Expand Down Expand Up @@ -328,7 +333,7 @@ func (state *ArbosState) UpgradeArbosVersion(
)
}
// Update Brotli compression level for fast compression from 0 to 1
ensure(state.l1PricingState.SetBrotliCompressionLevel(1))
ensure(state.SetBrotliCompressionLevel(1))
default:
return fmt.Errorf(
"the chain is upgrading to unsupported ArbOS version %v, %w",
Expand Down Expand Up @@ -390,6 +395,17 @@ func (state *ArbosState) SetFormatVersion(val uint64) {
state.Restrict(state.backingStorage.SetUint64ByUint64(uint64(versionOffset), val))
}

func (state *ArbosState) BrotliCompressionLevel() (uint64, error) {
return state.brotliCompressionLevel.Get()
}

func (state *ArbosState) SetBrotliCompressionLevel(val uint64) error {
if val <= arbcompress.LEVEL_WELL {
return state.brotliCompressionLevel.Set(val)
}
return errors.New("invalid brotli compression level")
}

func (state *ArbosState) RetryableState() *retryables.RetryableState {
return state.retryableState
}
Expand Down
6 changes: 5 additions & 1 deletion arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ func ProduceBlockAdvanced(

if basefee.Sign() > 0 {
dataGas = math.MaxUint64
posterCost, _ := state.L1PricingState().GetPosterInfo(tx, poster)
brotliCompressionLevel, err := state.BrotliCompressionLevel()
if err != nil {
return nil, nil, fmt.Errorf("failed to get brotliCompressionLevel: %w", err)
}
posterCost, _ := state.L1PricingState().GetPosterInfo(tx, poster, brotliCompressionLevel)
posterCostInL2Gas := arbmath.BigDiv(posterCost, basefee)

if posterCostInL2Gas.IsUint64() {
Expand Down
51 changes: 14 additions & 37 deletions arbos/l1pricing/l1pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ type L1PricingState struct {
inertia storage.StorageBackedUint64
perUnitReward storage.StorageBackedUint64
// variables
lastUpdateTime storage.StorageBackedUint64 // timestamp of the last update from L1 that we processed
fundsDueForRewards storage.StorageBackedBigInt
brotliCompressionLevel storage.StorageBackedUint64 // brotli compression level used for pricing
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
unitsSinceUpdate storage.StorageBackedUint64 // calldata units collected for since last update
pricePerUnit storage.StorageBackedBigUint // current price per calldata unit
Expand All @@ -64,7 +63,6 @@ const (
perUnitRewardOffset
lastUpdateTimeOffset
fundsDueForRewardsOffset
brotliCompressionLevelOffset
unitsSinceOffset
pricePerUnitOffset
lastSurplusOffset
Expand All @@ -74,11 +72,10 @@ const (
)

const (
InitialInertia = 10
InitialPerUnitReward = 10
InitialPerBatchGasCostV6 = 100_000
InitialPerBatchGasCostV12 = 210_000 // overriden as part of the upgrade
InitialBrotliCompressionLevel = 0
InitialInertia = 10
InitialPerUnitReward = 10
InitialPerBatchGasCostV6 = 100_000
InitialPerBatchGasCostV12 = 210_000 // overriden as part of the upgrade
)

// one minute at 100000 bytes / sec
Expand Down Expand Up @@ -115,10 +112,6 @@ func InitializeL1PricingState(sto *storage.Storage, initialRewardsRecipient comm
if err := pricePerUnit.SetSaturatingWithWarning(initialL1BaseFee, "initial L1 base fee (storing in price per unit)"); err != nil {
return err
}
brotliCompressionLevel := sto.OpenStorageBackedUint64(brotliCompressionLevelOffset)
if err := brotliCompressionLevel.Set(InitialBrotliCompressionLevel); err != nil {
return err
}
return nil
}

Expand All @@ -132,7 +125,6 @@ func OpenL1PricingState(sto *storage.Storage) *L1PricingState {
sto.OpenStorageBackedUint64(perUnitRewardOffset),
sto.OpenStorageBackedUint64(lastUpdateTimeOffset),
sto.OpenStorageBackedBigInt(fundsDueForRewardsOffset),
sto.OpenStorageBackedUint64(brotliCompressionLevelOffset),
sto.OpenStorageBackedUint64(unitsSinceOffset),
sto.OpenStorageBackedBigUint(pricePerUnitOffset),
sto.OpenStorageBackedBigInt(lastSurplusOffset),
Expand Down Expand Up @@ -262,17 +254,6 @@ func (ps *L1PricingState) SetL1FeesAvailable(val *big.Int) error {
return ps.l1FeesAvailable.SetChecked(val)
}

func (ps *L1PricingState) BrotliCompressionLevel() (uint64, error) {
return ps.brotliCompressionLevel.Get()
}

func (ps *L1PricingState) SetBrotliCompressionLevel(val uint64) error {
if val <= arbcompress.LEVEL_WELL {
return ps.brotliCompressionLevel.Set(val)
}
return errors.New("invalid brotli compression level")
}

func (ps *L1PricingState) AddToL1FeesAvailable(delta *big.Int) (*big.Int, error) {
old, err := ps.L1FeesAvailable()
if err != nil {
Expand Down Expand Up @@ -508,7 +489,7 @@ func (ps *L1PricingState) UpdateForBatchPosterSpending(
return nil
}

func (ps *L1PricingState) getPosterUnitsWithoutCache(tx *types.Transaction, posterAddr common.Address) uint64 {
func (ps *L1PricingState) getPosterUnitsWithoutCache(tx *types.Transaction, posterAddr common.Address, brotliCompressionLevel uint64) uint64 {

if posterAddr != BatchPosterAddress {
return 0
Expand All @@ -519,25 +500,21 @@ func (ps *L1PricingState) getPosterUnitsWithoutCache(tx *types.Transaction, post
return 0
}

level, err := ps.BrotliCompressionLevel()
if err != nil {
panic(fmt.Sprintf("failed to get brotli compression level: %v", err))
}
l1Bytes, err := byteCountAfterBrotliLevel(txBytes, int(level))
l1Bytes, err := byteCountAfterBrotliLevel(txBytes, int(brotliCompressionLevel))
if err != nil {
panic(fmt.Sprintf("failed to compress tx: %v", err))
}
return l1Bytes * params.TxDataNonZeroGasEIP2028
}

// GetPosterInfo returns the poster cost and the calldata units for a transaction
func (ps *L1PricingState) GetPosterInfo(tx *types.Transaction, poster common.Address) (*big.Int, uint64) {
func (ps *L1PricingState) GetPosterInfo(tx *types.Transaction, poster common.Address, brotliCompressionLevel uint64) (*big.Int, uint64) {
if poster != BatchPosterAddress {
return common.Big0, 0
}
units := atomic.LoadUint64(&tx.CalldataUnits)
if units == 0 {
units = ps.getPosterUnitsWithoutCache(tx, poster)
units = ps.getPosterUnitsWithoutCache(tx, poster, brotliCompressionLevel)
atomic.StoreUint64(&tx.CalldataUnits, units)
}

Expand Down Expand Up @@ -593,23 +570,23 @@ func makeFakeTxForMessage(message *core.Message) *types.Transaction {
})
}

func (ps *L1PricingState) PosterDataCost(message *core.Message, poster common.Address) (*big.Int, uint64) {
func (ps *L1PricingState) PosterDataCost(message *core.Message, poster common.Address, brotliCompressionLevel uint64) (*big.Int, uint64) {
tx := message.Tx
if tx != nil {
return ps.GetPosterInfo(tx, poster)
return ps.GetPosterInfo(tx, poster, brotliCompressionLevel)
}

// Otherwise, we don't have an underlying transaction, so we're likely in gas estimation.
// We'll instead make a fake tx from the message info we do have, and then pad our cost a bit to be safe.
tx = makeFakeTxForMessage(message)
units := ps.getPosterUnitsWithoutCache(tx, poster)
units := ps.getPosterUnitsWithoutCache(tx, poster, brotliCompressionLevel)
units = arbmath.UintMulByBips(units+estimationPaddingUnits, arbmath.OneInBips+estimationPaddingBasisPoints)
pricePerUnit, _ := ps.PricePerUnit()
return am.BigMulByUint(pricePerUnit, units), units
}

func byteCountAfterBrotliLevel(input []byte, level int) (uint64, error) {
compressed, err := arbcompress.CompressFast(input, level)
compressed, err := arbcompress.CompressLevel(input, level)
if err != nil {
return 0, err
}
Expand Down
6 changes: 5 additions & 1 deletion arbos/tx_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,11 @@ func (p *TxProcessor) GasChargingHook(gasRemaining *uint64) (common.Address, err
// Since tips go to the network, and not to the poster, we use the basefee.
// Note, this only determines the amount of gas bought, not the price per gas.

posterCost, calldataUnits := p.state.L1PricingState().PosterDataCost(p.msg, poster)
brotliCompressionLevel, err := p.state.BrotliCompressionLevel()
if err != nil {
return common.Address{}, fmt.Errorf("failed to get brotliCompressionLevel: %w", err)
}
posterCost, calldataUnits := p.state.L1PricingState().PosterDataCost(p.msg, poster, brotliCompressionLevel)
if calldataUnits > 0 {
p.state.Restrict(p.state.L1PricingState().AddToUnitsSinceUpdate(calldataUnits))
}
Expand Down
12 changes: 10 additions & 2 deletions nodeInterface/NodeInterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,11 @@ func (n NodeInterface) GasEstimateL1Component(
// Compute the fee paid for L1 in L2 terms
// See in GasChargingHook that this does not induce truncation error
//
feeForL1, _ := pricing.PosterDataCost(msg, l1pricing.BatchPosterAddress)
brotliCompressionLevel, err := c.State.BrotliCompressionLevel()
if err != nil {
return 0, nil, nil, fmt.Errorf("failed to get brotliCompressionLevel: %w", err)
}
feeForL1, _ := pricing.PosterDataCost(msg, l1pricing.BatchPosterAddress, brotliCompressionLevel)
feeForL1 = arbmath.BigMulByBips(feeForL1, arbos.GasEstimationL1PricePadding)
gasForL1 := arbmath.BigDiv(feeForL1, baseFee).Uint64()
return gasForL1, baseFee, l1BaseFeeEstimate, nil
Expand Down Expand Up @@ -507,7 +511,11 @@ func (n NodeInterface) GasEstimateComponents(
if err != nil {
return 0, 0, nil, nil, err
}
feeForL1, _ := pricing.PosterDataCost(msg, l1pricing.BatchPosterAddress)
brotliCompressionLevel, err := c.State.BrotliCompressionLevel()
if err != nil {
return 0, 0, nil, nil, fmt.Errorf("failed to get brotliCompressionLevel: %w", err)
}
feeForL1, _ := pricing.PosterDataCost(msg, l1pricing.BatchPosterAddress, brotliCompressionLevel)

baseFee, err := c.State.L2PricingState().BaseFeeWei()
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion nodeInterface/virtual-contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ func init() {
return
}

posterCost, _ := state.L1PricingState().PosterDataCost(msg, l1pricing.BatchPosterAddress)
brotliCompressionLevel, err := state.BrotliCompressionLevel()
if err != nil {
log.Error("failed to get brotliCompressionLevel", "err", err)
return
}
posterCost, _ := state.L1PricingState().PosterDataCost(msg, l1pricing.BatchPosterAddress, brotliCompressionLevel)
posterCostInL2Gas := arbos.GetPosterGas(state, header.BaseFee, msg.TxRunMode, posterCost)
*gascap = arbmath.SaturatingUAdd(*gascap, posterCostInL2Gas)
}
Expand Down
2 changes: 1 addition & 1 deletion precompiles/ArbOwner.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error {
}

func (con ArbOwner) SetBrotliCompressionLevel(c ctx, evm mech, level uint64) error {
return c.State.L1PricingState().SetBrotliCompressionLevel(level)
return c.State.SetBrotliCompressionLevel(level)
}

func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease huge) (huge, error) {
Expand Down
2 changes: 1 addition & 1 deletion precompiles/ArbOwnerPublic.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ func (con ArbOwnerPublic) GetInfraFeeAccount(c ctx, evm mech) (addr, error) {

// GetBrotliCompressionLevel gets the current brotli compression level used for fast compression
func (con ArbOwnerPublic) GetBrotliCompressionLevel(c ctx, evm mech) (uint64, error) {
return c.State.L1PricingState().BrotliCompressionLevel()
return c.State.BrotliCompressionLevel()
}
2 changes: 1 addition & 1 deletion system_tests/fees_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ func TestSequencerPriceAdjustsFrom25Gwei(t *testing.T) {
func compressedTxSize(t *testing.T, tx *types.Transaction) uint64 {
txBin, err := tx.MarshalBinary()
Require(t, err)
compressed, err := arbcompress.CompressFast(txBin, l1pricing.InitialBrotliCompressionLevel)
compressed, err := arbcompress.CompressLevel(txBin, 0)
Require(t, err)
return uint64(len(compressed))
}
3 changes: 1 addition & 2 deletions system_tests/state_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/offchainlabs/nitro/arbos"
"github.com/offchainlabs/nitro/arbos/arbosState"
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/arbos/l1pricing"
"github.com/offchainlabs/nitro/arbos/l2pricing"
"github.com/offchainlabs/nitro/arbstate"
"github.com/offchainlabs/nitro/statetransfer"
Expand Down Expand Up @@ -175,7 +174,7 @@ func FuzzStateTransition(f *testing.F) {
binary.BigEndian.PutUint64(seqBatch[32:40], uint64(len(delayedMessages)))
if compressSeqMsg {
seqBatch = append(seqBatch, arbstate.BrotliMessageHeaderByte)
seqMsgCompressed, err := arbcompress.CompressFast(seqMsg, l1pricing.InitialBrotliCompressionLevel)
seqMsgCompressed, err := arbcompress.CompressLevel(seqMsg, 0)
if err != nil {
panic(fmt.Sprintf("failed to compress sequencer message: %v", err))
}
Expand Down

0 comments on commit 291f889

Please sign in to comment.