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
5 changes: 5 additions & 0 deletions .github/workflows/kurtosis-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
- name: Pre kurtosis run
uses: ./.github/actions/setup
with:
main_branch: develop
docker_username: ${{ secrets.DOCKERHUB }}
docker_token: ${{ secrets.DOCKERHUB_KEY }}

Expand Down Expand Up @@ -129,6 +130,9 @@ jobs:
- name: Inspect enclave
run: kurtosis enclave inspect ${{ env.ENCLAVE_NAME }}

- name: Sleep for 1 minute
run: sleep 60

- name: Test state syncs
uses: ./.github/actions/test-state-sync
with:
Expand Down Expand Up @@ -165,4 +169,5 @@ jobs:
if: always()
uses: ./.github/actions/cleanup
with:
main_branch: develop
enclave_name: ${{ env.ENCLAVE_NAME }}
2 changes: 2 additions & 0 deletions .github/workflows/kurtosis-stateless-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
- name: Pre kurtosis run
uses: ./.github/actions/setup
with:
main_branch: develop
docker_username: ${{ secrets.DOCKERHUB }}
docker_token: ${{ secrets.DOCKERHUB_KEY }}

Expand Down Expand Up @@ -154,4 +155,5 @@ jobs:
if: always()
uses: ./.github/actions/cleanup
with:
main_branch: develop
enclave_name: ${{ env.ENCLAVE_NAME }}
1 change: 1 addition & 0 deletions builder/files/genesis-amoy.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"madhugiriBlock": 28899616,
"madhugiriProBlock": 29287400,
"dandeliBlock": 31890000,
"lisovoBlock": 33634700,
"skipValidatorByteCheck": [26160367, 26161087, 26171567, 26173743, 26175647],
"stateSyncConfirmationDelay": {
"0": 128
Expand Down
35 changes: 24 additions & 11 deletions consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const (

// VerifyEIP1559Header verifies some header attributes which were changed in EIP-1559,
// - gas limit check
// - basefee check with different rules pre/post Dandeli:
// - Pre-Dandeli: Strict validation (baseFee must exactly match calculated value)
// - Post-Dandeli: Boundary validation (baseFee change must be within MaxBaseFeeChangePercent)
// - basefee check with different rules pre/post Lisovo:
// - Pre-Lisovo: Strict validation (baseFee must exactly match calculated value)
// - Post-Lisovo: Boundary validation (baseFee change must be within MaxBaseFeeChangePercent)
func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Header) error {
// Verify that the gas limit remains within allowed bounds
parentGasLimit := parent.GasLimit
Expand All @@ -54,12 +54,12 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
return errors.New("header is missing baseFee")
}

// Post-Dandeli: Validate that base fee changes are within allowed boundaries
if config.Bor != nil && config.Bor.IsDandeli(header.Number) {
// Post-Lisovo: Validate that base fee changes are within allowed boundaries
if config.Bor != nil && config.Bor.IsLisovo(header.Number) {
return verifyBaseFeeWithinBoundaries(parent, header)
}

// Pre-Dandeli: Verify the baseFee is correct based on the parent header
// Pre-Lisovo: Verify the baseFee is correct based on the parent header
expectedBaseFee := CalcBaseFee(config, parent)
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d",
Expand All @@ -70,13 +70,19 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
}

// verifyBaseFeeWithinBoundaries checks that the base fee change is within the allowed boundary.
// This prevents excessive fee volatility while allowing dynamic fee adjustment post-Dandeli.
// This prevents excessive fee volatility while allowing dynamic fee adjustment post-Lisovo.
// The boundary limit is defined by MaxBaseFeeChangePercent constant.
func verifyBaseFeeWithinBoundaries(parent, header *types.Header) error {
// Calculate the maximum allowed change (MaxBaseFeeChangePercent of parent base fee)
maxAllowedChange := new(big.Int).Mul(parent.BaseFee, big.NewInt(MaxBaseFeeChangePercent))
maxAllowedChange.Div(maxAllowedChange, big.NewInt(100))

// Ensure minimum 1 wei cap to prevent unlimited growth at very low base fees.
// This matches the logic in CalcBaseFee.
if maxAllowedChange.Cmp(common.Big1) < 0 {
maxAllowedChange = new(big.Int).Set(common.Big1)
}

// Calculate the actual change in base fee
actualChange := new(big.Int)
if header.BaseFee.Cmp(parent.BaseFee) >= 0 {
Expand Down Expand Up @@ -116,12 +122,19 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
baseFeeChangeDenominatorUint64 = params.BaseFeeChangeDenominator(config.Bor, parent.Number)
)

// Calculate maximum allowed change (only applies post-Dandeli)
// Calculate maximum allowed change (only applies post-Lisovo)
var maxAllowedChange *big.Int
applyBoundaryCap := config.Bor != nil && config.Bor.IsDandeli(parent.Number)
applyBoundaryCap := config.Bor != nil && config.Bor.IsLisovo(parent.Number)
if applyBoundaryCap {
maxAllowedChange = new(big.Int).Mul(parent.BaseFee, big.NewInt(MaxBaseFeeChangePercent))
maxAllowedChange.Div(maxAllowedChange, big.NewInt(100))

// Ensure minimum 1 wei cap to prevent unlimited growth at very low base fees.
// When percentage calculation rounds to 0 (baseFee < 20 wei), this ensures
// there's still an absolute cap of 1 wei per block.
if maxAllowedChange.Cmp(common.Big1) < 0 {
maxAllowedChange = new(big.Int).Set(common.Big1)
}
}

if parent.GasUsed > parentGasTarget {
Expand All @@ -132,7 +145,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(baseFeeChangeDenominatorUint64))

// Cap the increase to MaxBaseFeeChangePercent post-Dandeli
// Cap the increase to MaxBaseFeeChangePercent post-Lisovo
if applyBoundaryCap && num.Cmp(maxAllowedChange) > 0 {
num.Set(maxAllowedChange)
}
Expand All @@ -149,7 +162,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(baseFeeChangeDenominatorUint64))

// Cap the decrease to MaxBaseFeeChangePercent post-Dandeli
// Cap the decrease to MaxBaseFeeChangePercent post-Lisovo
if applyBoundaryCap && num.Cmp(maxAllowedChange) > 0 {
num.Set(maxAllowedChange)
}
Expand Down
14 changes: 8 additions & 6 deletions consensus/misc/eip1559/eip1559_basefee_boundary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ import (
"github.com/stretchr/testify/require"
)

// TestBaseFeeBoundary tests the MaxBaseFeeChangePercent base fee change limit post-Dandeli.
// TestBaseFeeBoundary tests the MaxBaseFeeChangePercent base fee change limit post-Lisovo.
// It verifies both the CalcBaseFee capping and VerifyEIP1559Header validation.
func TestBaseFeeBoundary(t *testing.T) {
t.Parallel()

testConfig := copyConfig(config())
testConfig.Bor.LisovoBlock = big.NewInt(15)
testConfig.Bor.DandeliBlock = big.NewInt(10)
testConfig.Bor.BhilaiBlock = big.NewInt(5)

Expand Down Expand Up @@ -141,8 +142,8 @@ func TestBaseFeeBoundary(t *testing.T) {
}
}

// TestBaseFeeBoundaryPreDandeli tests that pre-Dandeli blocks still use strict validation
func TestBaseFeeBoundaryPreDandeli(t *testing.T) {
// TestBaseFeeBoundaryPreLisovo tests that pre-Lisovo blocks still use strict validation
func TestBaseFeeBoundaryPreLisovo(t *testing.T) {
t.Parallel()

testConfig := copyConfig(config())
Expand Down Expand Up @@ -204,11 +205,12 @@ func TestBaseFeeBoundaryPreDandeli(t *testing.T) {
}

// TestAggressiveParametersExceedBoundary tests that aggressive parameter configurations
// (low denominators) are properly capped at MaxBaseFeeChangePercent by CalcBaseFee post-Dandeli
// (low denominators) are properly capped at MaxBaseFeeChangePercent by CalcBaseFee post-Lisovo
func TestAggressiveParametersExceedBoundary(t *testing.T) {
t.Parallel()

testConfig := copyConfig(config())
testConfig.Bor.LisovoBlock = big.NewInt(15)
testConfig.Bor.DandeliBlock = big.NewInt(10)
testConfig.Bor.BhilaiBlock = big.NewInt(5)

Expand Down Expand Up @@ -320,8 +322,8 @@ func TestAggressiveParametersExceedBoundary(t *testing.T) {
}
}

// TestDefaultParametersWithinBoundary documents and verifies that default post-Dandeli
// parameters stay well within the MaxBaseFeeChangePercent boundary at all gas usage levels
// TestDefaultParametersWithinBoundary documents and verifies that default post-Dandeli parameters
// (65% gas target) stay well within the MaxBaseFeeChangePercent boundary post-Lisovo at all gas usage levels
func TestDefaultParametersWithinBoundary(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading