Skip to content

Commit

Permalink
*: add custom target gas limit in cluster lock v1.10 (#3456)
Browse files Browse the repository at this point in the history
Up until now the gas limit was hardcoded to 30M. However, the community is pushing towards bumping those numbers and you can't really customise that in Charon.

With those updates a `targetGasLimit` variable is introduced to the cluster definition and a new version of cluster definition is created, v1.10. The previous default version was v1.8, now the default is set to v1.10, including also the changes of consensus protocol introduced in v1.9. However, good to keep in mind there is only 1 consensus protocol enabled in charon, meaning the consensus protocol configuration in v1.9 isn't making much difference.

Previously the gas limit was hardcoded to 30M, now this can be configured by supplying `--target-gas-limit` flag to both CreateDKG and CreateCluster commands. The variable is not compulsory and its default is set to 36M (this is the new value commonly used in the ecosystem). If a new charon version (i.e.: v1.3) uses old definition (and lock) file, its default will still be the previous one of 30M. To bump the number, unfortunately, a new cluster needs to be created with the updated definition version.

category: feature
ticket: #3419
  • Loading branch information
KaloyanTanev authored Jan 21, 2025
1 parent 69f0117 commit 6dacdd3
Show file tree
Hide file tree
Showing 31 changed files with 798 additions and 193 deletions.
3 changes: 2 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type Config struct {
ConsensusProtocol string
Nickname string
BeaconNodeHeaders []string
TargetGasLimit uint

TestConfig TestConfig
}
Expand Down Expand Up @@ -491,7 +492,7 @@ func wireCoreWorkflow(ctx context.Context, life *lifecycle.Manager, conf Config,

dutyDB := dutydb.NewMemDB(deadlinerFunc("dutydb"))

vapi, err := validatorapi.NewComponent(eth2Cl, allPubSharesByKey, nodeIdx.ShareIdx, feeRecipientFunc, conf.BuilderAPI, seenPubkeys)
vapi, err := validatorapi.NewComponent(eth2Cl, allPubSharesByKey, nodeIdx.ShareIdx, feeRecipientFunc, conf.BuilderAPI, uint(cluster.GetTargetGasLimit()), seenPubkeys)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions app/obolapi/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestLockPublish(t *testing.T) {
opts := []func(d *cluster.Definition){
func(d *cluster.Definition) {
d.Version = "v1.5.0"
d.TargetGasLimit = 0
},
}

Expand Down
41 changes: 24 additions & 17 deletions cluster/cluster_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ func TestDefinitionVerify(t *testing.T) {
secret3, creator := randomCreator(t)

t.Run("verify definition v1.5 solo", func(t *testing.T) {
definition := randomDefinition(t, creator, Operator{}, Operator{},
definition := randomDefinition(t, creator, Operator{}, Operator{}, 0,
WithVersion(v1_5),
func(d *Definition) { d.TargetGasLimit = 0 },
)

definition, err = signCreator(secret3, definition)
Expand All @@ -34,8 +35,9 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("verify definition v1.5", func(t *testing.T) {
definition := randomDefinition(t, creator, op0, op1,
definition := randomDefinition(t, creator, op0, op1, 0,
WithVersion(v1_5),
func(d *Definition) { d.TargetGasLimit = 0 },
)

definition, err = signCreator(secret3, definition)
Expand All @@ -52,9 +54,10 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("verify definition v1.4", func(t *testing.T) {
definition := randomDefinition(t, creator, op0, op1,
definition := randomDefinition(t, creator, op0, op1, 0,
WithVersion(v1_4),
WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress()),
func(d *Definition) { d.TargetGasLimit = 0 },
)

definition, err = signCreator(secret3, definition)
Expand All @@ -71,9 +74,10 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("verify definition v1.3", func(t *testing.T) {
definition := randomDefinition(t, Creator{}, op0, op1,
definition := randomDefinition(t, Creator{}, op0, op1, 0,
WithVersion(v1_3),
WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress()),
func(d *Definition) { d.TargetGasLimit = 0 },
)

definition.Operators[0], err = signOperator(secret0, definition, op0)
Expand All @@ -87,31 +91,34 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("verify definition v1.2 or lower", func(t *testing.T) {
def := randomDefinition(t, Creator{}, op0, op1,
def := randomDefinition(t, Creator{}, op0, op1, 0,
WithVersion(v1_2),
WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress()),
func(d *Definition) { d.TargetGasLimit = 0 },
)
require.NoError(t, def.VerifySignatures())

def = randomDefinition(t, Creator{}, op0, op1,
def = randomDefinition(t, Creator{}, op0, op1, 0,
WithVersion(v1_0),
WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress()),
func(d *Definition) { d.TargetGasLimit = 0 },
)
require.NoError(t, def.VerifySignatures())
})

t.Run("unsigned creator and operators", func(t *testing.T) {
def := randomDefinition(t, creator, op0, op1)
def := randomDefinition(t, creator, op0, op1, 30000000)
def.Creator = Creator{}
def.Operators = []Operator{{}, {}}

require.NoError(t, def.VerifySignatures())
})

t.Run("unsigned operators v1.3", func(t *testing.T) {
def := randomDefinition(t, creator, op0, op1,
def := randomDefinition(t, creator, op0, op1, 0,
WithVersion(v1_3),
WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress()),
func(d *Definition) { d.TargetGasLimit = 0 },
)

def.Operators = []Operator{{}, {}}
Expand All @@ -120,7 +127,7 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("empty operator signatures", func(t *testing.T) {
def := randomDefinition(t, creator, op0, op1)
def := randomDefinition(t, creator, op0, op1, 30000000)

// Empty ENR sig
err := def.VerifySignatures()
Expand All @@ -135,7 +142,7 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("some operators didn't sign", func(t *testing.T) {
definition := randomDefinition(t, creator, op0, op1)
definition := randomDefinition(t, creator, op0, op1, 30000000)
definition.Operators[0] = Operator{} // Operator with no address, enr sig or config sig

// Only operator 1 signed.
Expand All @@ -148,14 +155,14 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("no operators no creator", func(t *testing.T) {
definition := randomDefinition(t, Creator{}, Operator{}, Operator{})
definition := randomDefinition(t, Creator{}, Operator{}, Operator{}, 30000000)

err = definition.VerifySignatures()
require.NoError(t, err)
})

t.Run("creator didn't sign", func(t *testing.T) {
definition := randomDefinition(t, creator, op0, op1)
definition := randomDefinition(t, creator, op0, op1, 30000000)
definition.Operators[0], err = signOperator(secret0, definition, op0)
require.NoError(t, err)

Expand All @@ -168,7 +175,7 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("solo flow definition empty operators slice", func(t *testing.T) {
definition := randomDefinition(t, creator, Operator{}, Operator{}, func(def *Definition) {
definition := randomDefinition(t, creator, Operator{}, Operator{}, 30000000, func(def *Definition) {
def.Operators = []Operator{}
})

Expand All @@ -186,7 +193,7 @@ func TestDefinitionVerify(t *testing.T) {
})

t.Run("solo flow definition empty operator structs", func(t *testing.T) {
definition := randomDefinition(t, creator, Operator{}, Operator{}, func(definition *Definition) {
definition := randomDefinition(t, creator, Operator{}, Operator{}, 30000000, func(definition *Definition) {
definition.Name = "solo flow"
})

Expand Down Expand Up @@ -233,8 +240,8 @@ func randomOperator(t *testing.T) (*k1.PrivateKey, Operator) {
}
}

// randomDefinition returns a test cluster definition with version set to v1.4.0.
func randomDefinition(t *testing.T, cr Creator, op0, op1 Operator, opts ...func(*Definition)) Definition {
// randomDefinition returns a test cluster definition with version set to default.
func randomDefinition(t *testing.T, cr Creator, op0, op1 Operator, targetGasLimit uint, opts ...func(*Definition)) Definition {
t.Helper()

const (
Expand All @@ -250,7 +257,7 @@ func randomDefinition(t *testing.T, cr Creator, op0, op1 Operator, opts ...func(

definition, err := NewDefinition("test definition", numVals, threshold,
feeRecipientAddrs, withdrawalAddrs, eth2util.Sepolia.GenesisForkVersionHex, cr, []Operator{op0, op1}, nil,
"qbft", rand.New(rand.NewSource(1)), opts...)
"qbft", targetGasLimit, rand.New(rand.NewSource(1)), opts...)
require.NoError(t, err)

return definition
Expand Down
36 changes: 24 additions & 12 deletions cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ import (
//go:generate go test . -v -update -clean

const (
v1_9 = "v1.9.0"
v1_8 = "v1.8.0"
v1_7 = "v1.7.0"
v1_6 = "v1.6.0"
v1_5 = "v1.5.0"
v1_4 = "v1.4.0"
v1_3 = "v1.3.0"
v1_2 = "v1.2.0"
v1_1 = "v1.1.0"
v1_0 = "v1.0.0"
v1_10 = "v1.10.0"
v1_9 = "v1.9.0"
v1_8 = "v1.8.0"
v1_7 = "v1.7.0"
v1_6 = "v1.6.0"
v1_5 = "v1.5.0"
v1_4 = "v1.4.0"
v1_3 = "v1.3.0"
v1_2 = "v1.2.0"
v1_1 = "v1.1.0"
v1_0 = "v1.0.0"
)

// TestEncode tests whether charon can correctly encode lock and definition files.
Expand Down Expand Up @@ -63,10 +64,15 @@ func TestEncode(t *testing.T) {
}

var partialAmounts []int
if isAnyVersion(version, v1_8, v1_9) {
if isAnyVersion(version, v1_8, v1_9, v1_10) {
partialAmounts = []int{16, 16}
}

targetGasLimit := uint(0)
if isAnyVersion(version, v1_10) {
targetGasLimit = 30000000
}

definition, err := cluster.NewDefinition(
"test definition",
numVals,
Expand Down Expand Up @@ -94,6 +100,7 @@ func TestEncode(t *testing.T) {
},
partialAmounts,
"abft",
targetGasLimit,
rand.New(rand.NewSource(0)),
opts...,
)
Expand Down Expand Up @@ -123,6 +130,11 @@ func TestEncode(t *testing.T) {
definition.ConsensusProtocol = ""
}

// Definition version prior to v1.10.0 don't support TargetGasLimit.
if isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9) {
definition.TargetGasLimit = 0
}

t.Run("definition_json_"+vStr, func(t *testing.T) {
testutil.RequireGoldenJSON(t, definition,
testutil.WithFilename("cluster_definition_"+vStr+".json"))
Expand Down Expand Up @@ -197,7 +209,7 @@ func TestEncode(t *testing.T) {
}

// Lock versions v1.8.0 and later support multiple PartialDepositData.
if isAnyVersion(version, v1_8, v1_9) {
if !isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7) {
for i := range lock.Validators {
dd := cluster.RandomDepositDataSeed(r)
dd.PubKey = lock.Validators[i].PubKey
Expand Down
Loading

0 comments on commit 6dacdd3

Please sign in to comment.