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

add methods to configure brotli compression level in ArbOS 12 #1865

Merged
merged 13 commits into from
Sep 28, 2023
Merged
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ $(arbitrator_jit): $(DEP_PREDICATE) .make/cbrotli-lib $(jit_files)
$(arbitrator_cases)/rust/target/wasm32-wasi/release/%.wasm: $(arbitrator_cases)/rust/src/bin/%.rs $(arbitrator_cases)/rust/src/lib.rs
cargo build --manifest-path $(arbitrator_cases)/rust/Cargo.toml --release --target wasm32-wasi --bin $(patsubst $(arbitrator_cases)/rust/target/wasm32-wasi/release/%.wasm,%, $@)

$(arbitrator_cases)/go/main: $(arbitrator_cases)/go/main.go
$(arbitrator_cases)/go/main: $(arbitrator_cases)/go/main.go .make/solgen
cd $(arbitrator_cases)/go && GOOS=js GOARCH=wasm go build main.go

$(arbitrator_generated_header): $(DEP_PREDICATE) arbitrator/prover/src/lib.rs arbitrator/prover/src/utils.rs
Expand Down
5 changes: 2 additions & 3 deletions arbcompress/compress_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

package arbcompress

const LEVEL_FAST = 0
const LEVEL_WELL = 11
const WINDOW_SIZE = 22 // BROTLI_DEFAULT_WINDOW

func compressedBufferSizeFor(length int) int {
return length + (length>>10)*8 + 64 // actual limit is: length + (length >> 14) * 4 + 6
}

func CompressFast(input []byte) ([]byte, error) {
return compressLevel(input, LEVEL_FAST)
func CompressFast(input []byte, level int) ([]byte, error) {
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
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)
compressedFast, err := CompressFast(data, 0)
if err != nil {
t.Fatal(err)
}
Expand Down
3 changes: 2 additions & 1 deletion arbitrator/prover/test-cases/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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 @@ -42,7 +43,7 @@ func MerkleSample(data [][]byte, toproove int) (bool, error) {
}

func testCompression(data []byte) {
compressed, err := arbcompress.CompressFast(data)
compressed, err := arbcompress.CompressFast(data, l1pricing.InitialBrotliCompressionLevel)
if err != nil {
panic(err)
}
Expand Down
11 changes: 11 additions & 0 deletions arbos/arbosState/arbosstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,17 @@ func (state *ArbosState) UpgradeArbosVersion(
if !firstTime {
ensure(state.chainOwners.ClearList())
}
case 11:
if !chainConfig.DebugMode() {
// This upgrade isn't finalized so we only want to support it for testing
return fmt.Errorf(
"the chain is upgrading to unsupported ArbOS version %v, %w",
state.arbosVersion+1,
ErrFatalNodeOutOfDate,
)
}
// Update Brotli compression level for fast compression from 0 to 1
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
ensure(state.l1PricingState.SetBrotliCompressionLevel(1))
default:
return fmt.Errorf(
"the chain is upgrading to unsupported ArbOS version %v, %w",
Expand Down
41 changes: 32 additions & 9 deletions arbos/l1pricing/l1pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ 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
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
// 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 @@ -63,6 +64,7 @@ const (
perUnitRewardOffset
lastUpdateTimeOffset
fundsDueForRewardsOffset
brotliCompressionLevelOffset
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
unitsSinceOffset
pricePerUnitOffset
lastSurplusOffset
Expand All @@ -72,10 +74,11 @@ const (
)

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

// one minute at 100000 bytes / sec
Expand Down Expand Up @@ -112,6 +115,10 @@ 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 @@ -125,6 +132,7 @@ 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 @@ -254,6 +262,17 @@ 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 @@ -500,7 +519,11 @@ func (ps *L1PricingState) getPosterUnitsWithoutCache(tx *types.Transaction, post
return 0
}

l1Bytes, err := byteCountAfterBrotli0(txBytes)
level, err := ps.BrotliCompressionLevel()
if err != nil {
panic(fmt.Sprintf("failed to get brotli compression level: %v", err))
}
l1Bytes, err := byteCountAfterBrotliLevel(txBytes, int(level))
if err != nil {
panic(fmt.Sprintf("failed to compress tx: %v", err))
}
Expand Down Expand Up @@ -585,8 +608,8 @@ func (ps *L1PricingState) PosterDataCost(message *core.Message, poster common.Ad
return am.BigMulByUint(pricePerUnit, units), units
}

func byteCountAfterBrotli0(input []byte) (uint64, error) {
compressed, err := arbcompress.CompressFast(input)
func byteCountAfterBrotliLevel(input []byte, level int) (uint64, error) {
compressed, err := arbcompress.CompressFast(input, level)
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion contracts
4 changes: 4 additions & 0 deletions precompiles/ArbOwner.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error {
return c.State.L1PricingState().SetAmortizedCostCapBips(cap)
}

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

func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease huge) (huge, error) {
balance := evm.StateDB.GetBalance(l1pricing.L1PricerFundsPoolAddress)
l1p := c.State.L1PricingState()
Expand Down
5 changes: 5 additions & 0 deletions precompiles/ArbOwnerPublic.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ func (con ArbOwnerPublic) GetInfraFeeAccount(c ctx, evm mech) (addr, error) {
}
return c.State.InfraFeeAccount()
}

// 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()
}
2 changes: 2 additions & 0 deletions precompiles/precompile.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ func Precompiles() map[addr]ArbosPrecompile {
ArbOwnerPublic := insert(MakePrecompile(templates.ArbOwnerPublicMetaData, &ArbOwnerPublic{Address: hex("6b")}))
ArbOwnerPublic.methodsByName["GetInfraFeeAccount"].arbosVersion = 5
ArbOwnerPublic.methodsByName["RectifyChainOwner"].arbosVersion = 11
ArbOwnerPublic.methodsByName["GetBrotliCompressionLevel"].arbosVersion = 12

ArbRetryableImpl := &ArbRetryableTx{Address: types.ArbRetryableTxAddress}
ArbRetryable := insert(MakePrecompile(templates.ArbRetryableTxMetaData, ArbRetryableImpl))
Expand Down Expand Up @@ -589,6 +590,7 @@ func Precompiles() map[addr]ArbosPrecompile {
ArbOwner.methodsByName["SetInfraFeeAccount"].arbosVersion = 5
ArbOwner.methodsByName["ReleaseL1PricerSurplusFunds"].arbosVersion = 10
ArbOwner.methodsByName["SetChainConfig"].arbosVersion = 11
ArbOwner.methodsByName["SetBrotliCompressionLevel"].arbosVersion = 12

insert(ownerOnly(ArbOwnerImpl.Address, ArbOwner, emitOwnerActs))
insert(debugOnly(MakePrecompile(templates.ArbDebugMetaData, &ArbDebug{Address: hex("ff")})))
Expand Down
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)
compressed, err := arbcompress.CompressFast(txBin, l1pricing.InitialBrotliCompressionLevel)
Require(t, err)
return uint64(len(compressed))
}
3 changes: 2 additions & 1 deletion system_tests/state_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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 @@ -174,7 +175,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)
seqMsgCompressed, err := arbcompress.CompressFast(seqMsg, l1pricing.InitialBrotliCompressionLevel)
if err != nil {
panic(fmt.Sprintf("failed to compress sequencer message: %v", err))
}
Expand Down
Loading