diff --git a/app/app.go b/app/app.go index 01768b0da..7be6b55bb 100644 --- a/app/app.go +++ b/app/app.go @@ -95,6 +95,7 @@ type Config struct { ProcDirectory string ConsensusProtocol string Nickname string + TargetGasLimit uint TestConfig TestConfig } @@ -490,7 +491,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 } diff --git a/app/obolapi/api_test.go b/app/obolapi/api_test.go index bb6f0de1f..bda4d1226 100644 --- a/app/obolapi/api_test.go +++ b/app/obolapi/api_test.go @@ -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 }, } diff --git a/app/peerinfo/peerinfo.go b/app/peerinfo/peerinfo.go index 788af6c52..3f570372e 100644 --- a/app/peerinfo/peerinfo.go +++ b/app/peerinfo/peerinfo.go @@ -202,7 +202,7 @@ func (p *PeerInfo) sendOnce(ctx context.Context, now time.Time) { name := p2p.PeerName(peerID) - p.nicknames[name] = resp.Nickname + p.nicknames[name] = resp.GetNickname() log.Info(ctx, "Peer name to nickname mappings", z.Any("nicknames", p.nicknames)) // Validator git hash with regex. diff --git a/cluster/cluster_internal_test.go b/cluster/cluster_internal_test.go index d09fc89dd..7724e787f 100644 --- a/cluster/cluster_internal_test.go +++ b/cluster/cluster_internal_test.go @@ -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) @@ -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) @@ -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) @@ -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) @@ -87,21 +91,23 @@ 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{{}, {}} @@ -109,9 +115,10 @@ func TestDefinitionVerify(t *testing.T) { }) 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{{}, {}} @@ -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() @@ -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. @@ -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) @@ -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{} }) @@ -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" }) @@ -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 ( @@ -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 diff --git a/cluster/cluster_test.go b/cluster/cluster_test.go index e52a9b547..cc832b25e 100644 --- a/cluster/cluster_test.go +++ b/cluster/cluster_test.go @@ -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. @@ -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, @@ -94,6 +100,7 @@ func TestEncode(t *testing.T) { }, partialAmounts, "abft", + targetGasLimit, rand.New(rand.NewSource(0)), opts..., ) @@ -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")) @@ -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 diff --git a/cluster/definition.go b/cluster/definition.go index 4013a0434..b1b0cd5cc 100644 --- a/cluster/definition.go +++ b/cluster/definition.go @@ -64,14 +64,14 @@ func WithLegacyVAddrs(feeRecipientAddress, withdrawalAddress string) func(*Defin // The hashes are also populated accordingly. Note that the hashes need to be recalculated when any field is modified. func NewDefinition(name string, numVals int, threshold int, feeRecipientAddresses []string, withdrawalAddresses []string, forkVersionHex string, creator Creator, operators []Operator, depositAmounts []int, - consensusProtocol string, random io.Reader, opts ...func(*Definition), + consensusProtocol string, targetGasLimit uint, random io.Reader, opts ...func(*Definition), ) (Definition, error) { if len(feeRecipientAddresses) != numVals { return Definition{}, errors.New("insufficient fee-recipient addresses") } if len(withdrawalAddresses) != numVals { - return Definition{}, errors.New("insufficient fee-recipient addresses") + return Definition{}, errors.New("insufficient withdrawal addresses") } def := Definition{ @@ -86,6 +86,7 @@ func NewDefinition(name string, numVals int, threshold int, feeRecipientAddresse Creator: creator, DepositAmounts: deposit.EthsToGweis(depositAmounts), ConsensusProtocol: consensusProtocol, + TargetGasLimit: targetGasLimit, } for i := range numVals { @@ -109,6 +110,14 @@ func NewDefinition(name string, numVals int, threshold int, feeRecipientAddresse return Definition{}, errors.New("the version does not support partial deposits", z.Str("version", def.Version)) } + if def.TargetGasLimit != 0 && !supportTargetGasLimit(def.Version) { + return Definition{}, errors.New("the version does not support custom target gas limit", z.Str("version", def.Version)) + } + + if def.TargetGasLimit == 0 && supportTargetGasLimit(def.Version) { + return Definition{}, errors.New("target gas limit should be set", z.Str("version", def.Version)) + } + return def.SetDefinitionHashes() } @@ -160,8 +169,11 @@ type Definition struct { // ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". ConsensusProtocol string `config_hash:"12" definition_hash:"12" json:"consensus_protocol,omitempty" ssz:"ByteList[256]"` + // TargetGasLimit is the target block gas limit for the cluster. + TargetGasLimit uint `config_hash:"13" definition_hash:"13" json:"target_gas_limit" ssz:"uint64"` + // ConfigHash uniquely identifies a cluster definition excluding operator ENRs and signatures. - ConfigHash []byte `json:"config_hash,0xhex" ssz:"Bytes32" config_hash:"-" definition_hash:"13"` + ConfigHash []byte `json:"config_hash,0xhex" ssz:"Bytes32" config_hash:"-" definition_hash:"14"` // DefinitionHash uniquely identifies a cluster definition including operator ENRs and signatures. DefinitionHash []byte `json:"definition_hash,0xhex" ssz:"Bytes32" config_hash:"-" definition_hash:"-"` @@ -392,6 +404,8 @@ func (d Definition) MarshalJSON() ([]byte, error) { return marshalDefinitionV1x8(d2) case isAnyVersion(d2.Version, v1_9): return marshalDefinitionV1x9(d2) + case isAnyVersion(d2.Version, v1_10): + return marshalDefinitionV1x10(d2) default: return nil, errors.New("unsupported version") } @@ -446,6 +460,11 @@ func (d *Definition) UnmarshalJSON(data []byte) error { if err != nil { return err } + case isAnyVersion(version.Version, v1_10): + def, err = unmarshalDefinitionV1x10(data) + if err != nil { + return err + } default: return errors.New("unsupported version") } @@ -648,6 +667,35 @@ func marshalDefinitionV1x9(def Definition) ([]byte, error) { return resp, nil } +func marshalDefinitionV1x10(def Definition) ([]byte, error) { + resp, err := json.Marshal(definitionJSONv1x10{ + Name: def.Name, + UUID: def.UUID, + Version: def.Version, + Timestamp: def.Timestamp, + NumValidators: def.NumValidators, + Threshold: def.Threshold, + DKGAlgorithm: def.DKGAlgorithm, + ValidatorAddresses: validatorAddressesToJSON(def.ValidatorAddresses), + ForkVersion: def.ForkVersion, + ConfigHash: def.ConfigHash, + DefinitionHash: def.DefinitionHash, + Operators: operatorsToV1x2orLater(def.Operators), + Creator: creatorJSON{ + Address: def.Creator.Address, + ConfigSignature: def.Creator.ConfigSignature, + }, + DepositAmounts: def.DepositAmounts, + ConsensusProtocol: def.ConsensusProtocol, + TargetGasLimit: def.TargetGasLimit, + }) + if err != nil { + return nil, errors.Wrap(err, "marshal definition", z.Str("version", def.Version)) + } + + return resp, nil +} + func unmarshalDefinitionV1x0or1(data []byte) (def Definition, err error) { var defJSON definitionJSONv1x0or1 if err := json.Unmarshal(data, &defJSON); err != nil { @@ -847,6 +895,43 @@ func unmarshalDefinitionV1x9(data []byte) (def Definition, err error) { }, nil } +func unmarshalDefinitionV1x10(data []byte) (def Definition, err error) { + var defJSON definitionJSONv1x10 + if err := json.Unmarshal(data, &defJSON); err != nil { + return Definition{}, errors.Wrap(err, "unmarshal definition v1_10") + } + + if len(defJSON.ValidatorAddresses) != defJSON.NumValidators { + return Definition{}, errors.New("num_validators not matching validators length") + } + + if err := deposit.VerifyDepositAmounts(def.DepositAmounts); err != nil { + return Definition{}, errors.Wrap(err, "invalid deposit amounts") + } + + return Definition{ + Name: defJSON.Name, + UUID: defJSON.UUID, + Version: defJSON.Version, + Timestamp: defJSON.Timestamp, + NumValidators: defJSON.NumValidators, + Threshold: defJSON.Threshold, + DKGAlgorithm: defJSON.DKGAlgorithm, + ForkVersion: defJSON.ForkVersion, + ConfigHash: defJSON.ConfigHash, + DefinitionHash: defJSON.DefinitionHash, + Operators: operatorsFromV1x2orLater(defJSON.Operators), + ValidatorAddresses: validatorAddressesFromJSON(defJSON.ValidatorAddresses), + Creator: Creator{ + Address: defJSON.Creator.Address, + ConfigSignature: defJSON.Creator.ConfigSignature, + }, + DepositAmounts: defJSON.DepositAmounts, + ConsensusProtocol: defJSON.ConsensusProtocol, + TargetGasLimit: defJSON.TargetGasLimit, + }, nil +} + // supportEIP712Sigs returns true if the provided definition version supports EIP712 signatures. // Note that Definition versions prior to v1.3.0 don't support EIP712 signatures. func supportEIP712Sigs(version string) bool { @@ -858,6 +943,11 @@ func supportPartialDeposits(version string) bool { return !isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7) } +// supportTargetGasLimit returns true if the provided definition version supports custom target gas limit. +func supportTargetGasLimit(version string) bool { + return !isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9) +} + func eip712SigsPresent(operators []Operator) bool { for _, o := range operators { if len(o.ENRSignature) > 0 || len(o.ConfigSignature) > 0 { @@ -974,6 +1064,26 @@ type definitionJSONv1x9 struct { DefinitionHash ethHex `json:"definition_hash"` } +// definitionJSONv1x10 is the json formatter of Definition for versions v1.10 or later. +type definitionJSONv1x10 struct { + Name string `json:"name,omitempty"` + Creator creatorJSON `json:"creator"` + Operators []operatorJSONv1x2orLater `json:"operators"` + UUID string `json:"uuid"` + Version string `json:"version"` + Timestamp string `json:"timestamp,omitempty"` + NumValidators int `json:"num_validators"` + Threshold int `json:"threshold"` + ValidatorAddresses []validatorAddressesJSON `json:"validators"` + DKGAlgorithm string `json:"dkg_algorithm"` + ForkVersion ethHex `json:"fork_version"` + DepositAmounts []eth2p0.Gwei `json:"deposit_amounts"` + ConsensusProtocol string `json:"consensus_protocol"` + TargetGasLimit uint `json:"target_gas_limit"` + ConfigHash ethHex `json:"config_hash"` + DefinitionHash ethHex `json:"definition_hash"` +} + // Creator identifies the creator of a cluster definition. // Note the following struct tag meanings: // - json: json field name. Suffix 0xhex indicates bytes are formatted as 0x prefixed hex strings. diff --git a/cluster/examples/cluster-definition-006.json b/cluster/examples/cluster-definition-006.json new file mode 100644 index 000000000..925d683c4 --- /dev/null +++ b/cluster/examples/cluster-definition-006.json @@ -0,0 +1,55 @@ +{ + "name": "solo flow", + "creator": { + "address": "", + "config_signature": "" + }, + "operators": [ + { + "address": "", + "enr": "enr:-HW4QOOzaUkBDJxca3MoJItjqSv438Ko2ah4oYd6gUczVEReYp9e5Eo6fhwZIG7YYHqzXROm3VVAVX-tJ1W9IQC3XjiAgmlkgnY0iXNlY3AyNTZrMaECOuyMY6-I8YdN_zrY8FrKXdRBAyrGuaxug6eTR_tmQbw", + "config_signature": "", + "enr_signature": "" + }, + { + "address": "", + "enr": "enr:-HW4QHjmSl61pUW_gtIoJhqQ-tkB1M1Ovabr0Pp77EyAJD-QXC503L2d2gPgnPtzoxhuhgGjNk8CRSZqtYDNp6uhaaCAgmlkgnY0iXNlY3AyNTZrMaECZBJKObtiUVAbMO0GP09_Kro3AtBhkN30ZgKbNrBZkPo", + "config_signature": "", + "enr_signature": "" + }, + { + "address": "", + "enr": "enr:-HW4QHUvGyPKGZ4zDHG69PzFYPgJWKcZiwFV2HrU-41gVYTUCpvA6v-Tdyr4UGgfVHhc9tfMHHhDSlmRUAa-3nlqEnaAgmlkgnY0iXNlY3AyNTZrMaECOmWQK7FDxAtKLuZXWahsxOqIHQbX6WSnTKiJrdOIaZo", + "config_signature": "", + "enr_signature": "" + }, + { + "address": "", + "enr": "enr:-HW4QC7kiC4A1x0qVzoQAc_wdXcuTd0UYcOetICL6MJOXskdAjJmfF4pYgFMLx0fCGK3iiv8Cq_mQZ18bt9BvrbeegWAgmlkgnY0iXNlY3AyNTZrMaECXbfZRpz8MygZmrZoobn9dUrLKABO_eojFp1cemlv-18", + "config_signature": "", + "enr_signature": "" + } + ], + "uuid": "AAA47693-6F13-56CA-D1E1-A70D1E89F3A5", + "version": "v1.10.0", + "timestamp": "2025-01-09T12:51:06+02:00", + "num_validators": 2, + "threshold": 3, + "validators": [ + { + "fee_recipient_address": "0x0D941218c10b055f0907FE1BbE486ccdAa7e332A", + "withdrawal_address": "0x0D941218c10b055f0907FE1BbE486ccdAa7e332A" + }, + { + "fee_recipient_address": "0x0D941218c10b055f0907FE1BbE486ccdAa7e332A", + "withdrawal_address": "0x0D941218c10b055f0907FE1BbE486ccdAa7e332A" + } + ], + "dkg_algorithm": "default", + "fork_version": "0x01017000", + "deposit_amounts": null, + "consensus_protocol": "", + "target_gas_limit": 30000000, + "config_hash": "0x10ac111410084511b00cbbbd3fe11c649425a53f2db97322a70520b287089b86", + "definition_hash": "0xec542a3aa3dbdce4e57551b491e536eb1bf2abb46dba2c4d238a93075f19318a" +} diff --git a/cluster/lock.go b/cluster/lock.go index b8998440f..22d97137c 100644 --- a/cluster/lock.go +++ b/cluster/lock.go @@ -54,7 +54,7 @@ func (l Lock) MarshalJSON() ([]byte, error) { return marshalLockV1x6(l, lockHash) case isAnyVersion(l.Version, v1_7): return marshalLockV1x7(l, lockHash) - case isAnyVersion(l.Version, v1_8, v1_9): + case isAnyVersion(l.Version, v1_8, v1_9, v1_10): return marshalLockV1x8OrLater(l, lockHash) default: return nil, errors.New("unsupported version") @@ -102,7 +102,7 @@ func (l *Lock) UnmarshalJSON(data []byte) error { if err != nil { return err } - case isAnyVersion(version.Definition.Version, v1_8, v1_9): + case isAnyVersion(version.Definition.Version, v1_8, v1_9, v1_10): lock, err = unmarshalLockV1x8OrLater(data) if err != nil { return err diff --git a/cluster/manifest/cluster_test.go b/cluster/manifest/cluster_test.go index e6a77168b..80e06da44 100644 --- a/cluster/manifest/cluster_test.go +++ b/cluster/manifest/cluster_test.go @@ -13,6 +13,30 @@ import ( manifestpb "github.com/obolnetwork/charon/cluster/manifestpb/v1" ) +const ( + 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" +) + +func isAnyVersion(version string, list ...string) bool { + for _, v := range list { + if version == v { + return true + } + } + + return false +} + func TestDuplicateENRs(t *testing.T) { seed := 0 random := rand.New(rand.NewSource(int64(seed))) diff --git a/cluster/manifest/load_test.go b/cluster/manifest/load_test.go index c6524b7ad..4cb3f490d 100644 --- a/cluster/manifest/load_test.go +++ b/cluster/manifest/load_test.go @@ -111,10 +111,16 @@ func testLoadLegacy(t *testing.T, version string) { var opts []func(*cluster.Definition) opts = append(opts, cluster.WithVersion(version)) - if version < "v1.5.0" { + if isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4) { opts = append(opts, cluster.WithLegacyVAddrs(testutil.RandomETHAddress(), testutil.RandomETHAddress())) } + if isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9) { + opts = append(opts, func(d *cluster.Definition) { d.TargetGasLimit = 0 }) + } else { + opts = append(opts, func(d *cluster.Definition) { d.TargetGasLimit = 36000000 }) + } + seed := 0 random := rand.New(rand.NewSource(int64(seed))) lock, _, _ := cluster.NewForT(t, rand.Intn(10), k, n, seed, random, opts...) diff --git a/cluster/manifest/mutationlegacylock.go b/cluster/manifest/mutationlegacylock.go index 21b25f025..bc023f466 100644 --- a/cluster/manifest/mutationlegacylock.go +++ b/cluster/manifest/mutationlegacylock.go @@ -150,6 +150,7 @@ func transformLegacyLock(input *manifestpb.Cluster, signed *manifestpb.SignedMut DkgAlgorithm: lock.DKGAlgorithm, ForkVersion: lock.ForkVersion, ConsensusProtocol: lock.ConsensusProtocol, + TargetGasLimit: uint32(lock.TargetGasLimit), Validators: vals, Operators: ops, }, nil diff --git a/cluster/manifestpb/v1/manifest.pb.go b/cluster/manifestpb/v1/manifest.pb.go index f2b05b4ee..1e3172f70 100644 --- a/cluster/manifestpb/v1/manifest.pb.go +++ b/cluster/manifestpb/v1/manifest.pb.go @@ -33,6 +33,7 @@ type Cluster struct { Operators []*Operator `protobuf:"bytes,7,rep,name=operators,proto3" json:"operators,omitempty"` // Operators is the list of operators of the cluster. Validators []*Validator `protobuf:"bytes,8,rep,name=validators,proto3" json:"validators,omitempty"` // Validators is the list of validators of the cluster. ConsensusProtocol string `protobuf:"bytes,9,opt,name=consensus_protocol,json=consensusProtocol,proto3" json:"consensus_protocol,omitempty"` // ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". + TargetGasLimit uint32 `protobuf:"varint,10,opt,name=target_gas_limit,json=targetGasLimit,proto3" json:"target_gas_limit,omitempty"` // TargetGasLimit is the custom target gas limit for transactions. unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -130,6 +131,13 @@ func (x *Cluster) GetConsensusProtocol() string { return "" } +func (x *Cluster) GetTargetGasLimit() uint32 { + if x != nil { + return x.TargetGasLimit + } + return 0 +} + // Mutation mutates the cluster manifest. type Mutation struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -562,7 +570,7 @@ var file_cluster_manifestpb_v1_manifest_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, - 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x03, 0x0a, 0x07, 0x43, 0x6c, 0x75, + 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x03, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x4d, 0x75, 0x74, 0x61, @@ -588,57 +596,60 @@ var file_cluster_manifestpb_v1_manifest_proto_rawDesc = []byte{ 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x60, 0x0a, 0x08, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x83, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x75, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x59, 0x0a, 0x12, - 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x43, 0x0a, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, - 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6d, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, - 0x03, 0x65, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x72, 0x22, - 0xe8, 0x01, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, - 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, - 0x70, 0x75, 0x62, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x09, 0x70, 0x75, 0x62, 0x53, 0x68, 0x61, 0x72, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x66, - 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x66, 0x65, 0x65, 0x52, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x2d, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3a, - 0x0a, 0x19, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x17, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0d, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0a, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x20, 0x0a, - 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6a, - 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, - 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x62, 0x6f, 0x6c, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x2f, 0x63, 0x68, 0x61, 0x72, 0x6f, 0x6e, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x2f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x76, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x67, + 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x60, + 0x0a, 0x08, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x83, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x75, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x09, + 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x75, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x36, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x72, 0x22, 0xe8, 0x01, 0x0a, 0x09, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x5f, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, + 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x69, 0x74, + 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, + 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x20, 0x0a, 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, + 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6f, 0x62, 0x6f, 0x6c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x63, 0x68, 0x61, + 0x72, 0x6f, 0x6e, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/cluster/manifestpb/v1/manifest.proto b/cluster/manifestpb/v1/manifest.proto index 2ccea05fb..4959b8966 100644 --- a/cluster/manifestpb/v1/manifest.proto +++ b/cluster/manifestpb/v1/manifest.proto @@ -17,6 +17,7 @@ message Cluster { repeated Operator operators = 7; // Operators is the list of operators of the cluster. repeated Validator validators = 8; // Validators is the list of validators of the cluster. string consensus_protocol = 9; // ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". + uint32 target_gas_limit = 10; // TargetGasLimit is the custom target gas limit for transactions. } // Mutation mutates the cluster manifest. diff --git a/cluster/ssz.go b/cluster/ssz.go index 3d9c1030c..715dcc205 100644 --- a/cluster/ssz.go +++ b/cluster/ssz.go @@ -29,19 +29,22 @@ const ( // getDefinitionHashFunc returns the function to hash a definition based on the provided version. func getDefinitionHashFunc(version string) (func(Definition, ssz.HashWalker, bool) error, error) { - if isAnyVersion(version, v1_0, v1_1, v1_2) { + switch { + case isAnyVersion(version, v1_0, v1_1, v1_2): return hashDefinitionLegacy, nil - } else if isAnyVersion(version, v1_3, v1_4) { + case isAnyVersion(version, v1_3, v1_4): return hashDefinitionV1x3or4, nil - } else if isAnyVersion(version, v1_5, v1_6, v1_7) { + case isAnyVersion(version, v1_5, v1_6, v1_7): return hashDefinitionV1x5to7, nil - } else if isAnyVersion(version, v1_8) { + case isAnyVersion(version, v1_8): return hashDefinitionV1x8, nil - } else if isAnyVersion(version, v1_9) { - return hashDefinitionV1x9orLater, nil + case isAnyVersion(version, v1_9): + return hashDefinitionV1x9, nil + case isAnyVersion(version, v1_10): + return hashDefinitionV1x10, nil + default: + return nil, errors.New("unknown version", z.Str("version", version)) } - - return nil, errors.New("unknown version", z.Str("version", version)) } // hashDefinition returns a config or definition hash. The config hash excludes operator ENRs and signatures @@ -415,8 +418,8 @@ func hashDefinitionV1x5to7(d Definition, hh ssz.HashWalker, configOnly bool) err return hashDefinitionV1x5to9(d, hh, configOnly, nil) } -// hashDefinitionV1x8to9 hashes the new definition with extra fields. -func hashDefinitionV1x8to9(d Definition, hh ssz.HashWalker, configOnly bool, extra []hashExtraFields) error { +// hashDefinitionV1x8to10 hashes the new definition with extra fields. +func hashDefinitionV1x8to10(d Definition, hh ssz.HashWalker, configOnly bool, extra []hashExtraFields) error { return hashDefinitionV1x5to9(d, hh, configOnly, []hashExtraFields{ func(d Definition, hh ssz.HashWalker) error { // Field (11) 'DepositAmounts' uint64[256] @@ -443,12 +446,12 @@ func hashDefinitionV1x8to9(d Definition, hh ssz.HashWalker, configOnly bool, ext // hashDefinitionV1x8 hashes the new definition. func hashDefinitionV1x8(d Definition, hh ssz.HashWalker, configOnly bool) error { - return hashDefinitionV1x8to9(d, hh, configOnly, nil) + return hashDefinitionV1x8to10(d, hh, configOnly, nil) } -// hashDefinitionV1x9OrLater hashes the new definition. -func hashDefinitionV1x9orLater(d Definition, hh ssz.HashWalker, configOnly bool) error { - return hashDefinitionV1x8to9(d, hh, configOnly, []hashExtraFields{ +// hashDefinitionV1x9 hashes the new definition. +func hashDefinitionV1x9(d Definition, hh ssz.HashWalker, configOnly bool) error { + return hashDefinitionV1x8to10(d, hh, configOnly, []hashExtraFields{ func(d Definition, hh ssz.HashWalker) error { // Field (12) 'ConsensusProtocol' ByteList[256] return putByteList(hh, []byte(d.ConsensusProtocol), sszMaxName, "consensus_protocol") @@ -456,12 +459,27 @@ func hashDefinitionV1x9orLater(d Definition, hh ssz.HashWalker, configOnly bool) }) } +// hashDefinitionV1x10 hashes the new definition. +func hashDefinitionV1x10(d Definition, hh ssz.HashWalker, configOnly bool) error { + return hashDefinitionV1x8to10(d, hh, configOnly, []hashExtraFields{ + func(d Definition, hh ssz.HashWalker) error { + // Field (12) 'ConsensusProtocol' ByteList[256] + return putByteList(hh, []byte(d.ConsensusProtocol), sszMaxName, "consensus_protocol") + }, + func(d Definition, hh ssz.HashWalker) error { + // Field (13) 'TargetGasLimit' uint64 + hh.PutUint64(uint64(d.TargetGasLimit)) + return nil + }, + }) +} + // hashLock returns a lock hash. func hashLock(l Lock) ([32]byte, error) { var hashFunc func(Lock, ssz.HashWalker) error if isAnyVersion(l.Version, v1_0, v1_1, v1_2) { hashFunc = hashLockLegacy - } else if isAnyVersion(l.Version, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9) { + } else if isAnyVersion(l.Version, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9, v1_10) { hashFunc = hashLockV1x3orLater } else { return [32]byte{}, errors.New("unknown version") @@ -524,7 +542,7 @@ func getValidatorHashFunc(version string) (func(DistValidator, ssz.HashWalker, s return hashValidatorV1x3Or4, nil } else if isAnyVersion(version, v1_5, v1_6, v1_7) { return hashValidatorV1x5to7, nil - } else if isAnyVersion(version, v1_8, v1_9) { + } else if isAnyVersion(version, v1_8, v1_9, v1_10) { return hashValidatorV1x8OrLater, nil } @@ -716,7 +734,7 @@ func getDepositDataHashFunc(version string) (func(DepositData, ssz.HashWalker) e return func(DepositData, ssz.HashWalker) error { return nil }, nil } else if isAnyVersion(version, v1_6) { return hashDepositDataV1x6, nil - } else if isAnyVersion(version, v1_7, v1_8, v1_9) { + } else if isAnyVersion(version, v1_7, v1_8, v1_9, v1_10) { return hashDepositDataV1x7OrLater, nil } @@ -728,7 +746,7 @@ func getRegistrationHashFunc(version string) (func(BuilderRegistration, ssz.Hash if isAnyVersion(version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6) { // Noop hash function for v1.0 to v1.6 that do not support builder registration. return func(BuilderRegistration, ssz.HashWalker) error { return nil }, nil - } else if isAnyVersion(version, v1_7, v1_8, v1_9) { + } else if isAnyVersion(version, v1_7, v1_8, v1_9, v1_10) { return hashBuilderRegistration, nil } diff --git a/cluster/test_cluster.go b/cluster/test_cluster.go index b31714f8d..b16c57abc 100644 --- a/cluster/test_cluster.go +++ b/cluster/test_cluster.go @@ -117,7 +117,7 @@ func NewForT(t *testing.T, dv, k, n, seed int, random *rand.Rand, opts ...func(* def, err := NewDefinition("test cluster", dv, k, feeRecipientAddrs, withdrawalAddrs, eth2util.Goerli.GenesisForkVersionHex, creator, ops, nil, - "", randomReader, opts...) + "", 30000000, randomReader, opts...) require.NoError(t, err) // Definition version prior to v1.3.0 don't support EIP712 signatures. diff --git a/cluster/testdata/cluster_definition_v1_10_0.json b/cluster/testdata/cluster_definition_v1_10_0.json new file mode 100644 index 000000000..8b5579642 --- /dev/null +++ b/cluster/testdata/cluster_definition_v1_10_0.json @@ -0,0 +1,46 @@ +{ + "name": "test definition", + "creator": { + "address": "0x6325253fec738dd7a9e28bf921119c160f070244", + "config_signature": "0x0bf5059875921e668a5bdf2c7fc4844592d2572bcd0668d2d6c52f5054e2d0836bf84c7174cb7476364cc3dbd968b0f7172ed85794bb358b0c3b525da1786f9f1c" + }, + "operators": [ + { + "address": "0x094279db1944ebd7a19d0f7bbacbe0255aa5b7d4", + "enr": "enr://b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713f8d962d7c8d", + "config_signature": "0x019192c24224e2cafccae3a61fb586b14323a6bc8f9e7df1d929333ff993933bea6f5b3af6de0374366c4719e43a1b067d89bc7f01f1f573981659a44ff17a4c1c", + "enr_signature": "0x15a3b539eb1e5849c6077dbb5722f5717a289a266f97647981998ebea89c0b4b373970115e82ed6f4125c8fa7311e4d7defa922daae7786667f7e936cd4f24ab1c" + }, + { + "address": "0xdf866baa56038367ad6145de1ee8f4a8b0993ebd", + "enr": "enr://e56a156a8de563afa467d49dec6a40e9a1d007f033c2823061bdd0eaa59f8e4d", + "config_signature": "0xa6430105220d0b29688b734b8ea0f3ca9936e8461f10d77c96ea80a7a665f606f6a63b7f3dfd2567c18979e4d60f26686d9bf2fb26c901ff354cde1607ee294b1b", + "enr_signature": "0xf32b7c7822ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d184fc39d1734ff5716428953bb6865fcf92b0c3a17c9028be9914eb7649c1c" + } + ], + "uuid": "0194FDC2-FA2F-FCC0-41D3-FF12045B73C8", + "version": "v1.10.0", + "timestamp": "2022-07-19T18:19:58+02:00", + "num_validators": 2, + "threshold": 3, + "validators": [ + { + "fee_recipient_address": "0x52fdfc072182654f163f5f0f9a621d729566c74d", + "withdrawal_address": "0x81855ad8681d0d86d1e91e00167939cb6694d2c4" + }, + { + "fee_recipient_address": "0xeb9d18a44784045d87f3c67cf22746e995af5a25", + "withdrawal_address": "0x5fb90badb37c5821b6d95526a41a9504680b4e7c" + } + ], + "dkg_algorithm": "default", + "fork_version": "0x90000069", + "deposit_amounts": [ + "16000000000", + "16000000000" + ], + "consensus_protocol": "abft", + "target_gas_limit": 30000000, + "config_hash": "0xafad2b3c34a7579fdd38c7a8d2b9f1ea5c7d0f940d2fbbcd2a383258ce8d76a2", + "definition_hash": "0x174b33b12bcb1ed2313c3a7b1c11dd348ccf21db13d987b0c9722df44bd62da0" +} \ No newline at end of file diff --git a/cluster/testdata/cluster_lock_v1_10_0.json b/cluster/testdata/cluster_lock_v1_10_0.json new file mode 100644 index 000000000..d500947c8 --- /dev/null +++ b/cluster/testdata/cluster_lock_v1_10_0.json @@ -0,0 +1,116 @@ +{ + "cluster_definition": { + "name": "test definition", + "creator": { + "address": "0x6325253fec738dd7a9e28bf921119c160f070244", + "config_signature": "0x0bf5059875921e668a5bdf2c7fc4844592d2572bcd0668d2d6c52f5054e2d0836bf84c7174cb7476364cc3dbd968b0f7172ed85794bb358b0c3b525da1786f9f1c" + }, + "operators": [ + { + "address": "0x094279db1944ebd7a19d0f7bbacbe0255aa5b7d4", + "enr": "enr://b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713f8d962d7c8d", + "config_signature": "0x019192c24224e2cafccae3a61fb586b14323a6bc8f9e7df1d929333ff993933bea6f5b3af6de0374366c4719e43a1b067d89bc7f01f1f573981659a44ff17a4c1c", + "enr_signature": "0x15a3b539eb1e5849c6077dbb5722f5717a289a266f97647981998ebea89c0b4b373970115e82ed6f4125c8fa7311e4d7defa922daae7786667f7e936cd4f24ab1c" + }, + { + "address": "0xdf866baa56038367ad6145de1ee8f4a8b0993ebd", + "enr": "enr://e56a156a8de563afa467d49dec6a40e9a1d007f033c2823061bdd0eaa59f8e4d", + "config_signature": "0xa6430105220d0b29688b734b8ea0f3ca9936e8461f10d77c96ea80a7a665f606f6a63b7f3dfd2567c18979e4d60f26686d9bf2fb26c901ff354cde1607ee294b1b", + "enr_signature": "0xf32b7c7822ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d184fc39d1734ff5716428953bb6865fcf92b0c3a17c9028be9914eb7649c1c" + } + ], + "uuid": "0194FDC2-FA2F-FCC0-41D3-FF12045B73C8", + "version": "v1.10.0", + "timestamp": "2022-07-19T18:19:58+02:00", + "num_validators": 2, + "threshold": 3, + "validators": [ + { + "fee_recipient_address": "0x52fdfc072182654f163f5f0f9a621d729566c74d", + "withdrawal_address": "0x81855ad8681d0d86d1e91e00167939cb6694d2c4" + }, + { + "fee_recipient_address": "0xeb9d18a44784045d87f3c67cf22746e995af5a25", + "withdrawal_address": "0x5fb90badb37c5821b6d95526a41a9504680b4e7c" + } + ], + "dkg_algorithm": "default", + "fork_version": "0x90000069", + "deposit_amounts": [ + "16000000000", + "16000000000" + ], + "consensus_protocol": "abft", + "target_gas_limit": 30000000, + "config_hash": "0xafad2b3c34a7579fdd38c7a8d2b9f1ea5c7d0f940d2fbbcd2a383258ce8d76a2", + "definition_hash": "0x174b33b12bcb1ed2313c3a7b1c11dd348ccf21db13d987b0c9722df44bd62da0" + }, + "distributed_validators": [ + { + "distributed_public_key": "0x1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102", + "public_shares": [ + "0x975deda77e758579ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae5411947cb553d7694267aef", + "0x4ebcea406b32d6108bd68584f57e37caac6e33feaa3263a399437024ba9c9b14678a274f01a910ae295f6efbfe5f5abf" + ], + "builder_registration": { + "message": { + "fee_recipient": "0x89b79bf504cfb57c7601232d589baccea9d6e263", + "gas_limit": 30000000, + "timestamp": 1655733600, + "pubkey": "0x1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102" + }, + "signature": "0xd313c8a3b4c1c0e05447f4ba370eb36dbcfdec90b302dcdc3b9ef522e2a6f1ed0afec1f8e20faabedf6b162e717d3a748a58677a0c56348f8921a266b11d0f334c62fe52ba53af19779cb2948b6570ffa0b773963c130ad797ddeafe4e3ad29b" + }, + "partial_deposit_data": [ + { + "pubkey": "0x1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102", + "withdrawal_credentials": "0x76b0620556304a3e3eae14c28d0cea39d2901a52720da85ca1e4b38eaf3f44c6", + "amount": "5919415281453547599", + "signature": "0xc6ef8362f2f5640854c15dfcacaa8a2cecce5a3aba53ab705b18db94b4d338a5143e63408d8724b0cf3fae17a3f79be1072fb63c35d6042c4160f38ee9e2a9f3fb4ffb0019b454d522b5ffa17604193fb8966710a7960732ca52cf53c3f520c8" + }, + { + "pubkey": "0x1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102", + "withdrawal_credentials": "0xc7ae77ba1d259b188a4b21c86fbc23d728b45347eada650af24c56d0800a8691", + "amount": "8817733914007551237", + "signature": "0x332088a8b07590bafcccbec6177536401d9a2b7f512b54bfc9d00532adf5aaa7c3a96bc59b489f77d9042c5bce26b163defde5ee6a0fbb3e9346cef81f0ae9515ef30fa47a364e75aea9e111d596e685a591121966e031650d510354aa845580" + } + ] + }, + { + "distributed_public_key": "0x5125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00ce73bff706f7ff4b6f44090a32711f3208e4e", + "public_shares": [ + "0x4b89cb5165ce64002cbd9c2887aa113df2468928d5a23b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf", + "0x1fbfe831b10b7bf5b15c47a53dbf8e7dcafc9e138647a4b44ed4bce964ed47f74aa594468ced323cb76f0d3fac476c9f" + ], + "builder_registration": { + "message": { + "fee_recipient": "0x72e6415a761f03abaa40abc9448fddeb2191d945", + "gas_limit": 30000000, + "timestamp": 1655733600, + "pubkey": "0x5125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00ce73bff706f7ff4b6f44090a32711f3208e4e" + }, + "signature": "0xe65a31bd5d41e2d2ce9c2b17892f0fea1931a290220777a93143dfdcbfa68406e877073ff08834e197a4034aa48afa3f85b8a62708caebbac880b5b89b93da53810164402104e648b6226a1b78021851f5d9ac0f313a89ddfc454c5f8f72ac89" + }, + "partial_deposit_data": [ + { + "pubkey": "0x5125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00ce73bff706f7ff4b6f44090a32711f3208e4e", + "withdrawal_credentials": "0x0152e5d49435807f9d4b97be6fb77970466a5626fe33408cf9e88e2c797408a3", + "amount": "534275443587623213", + "signature": "0x329cfffd4a75e498320982c85aad70384859c05a4b13a1d5b2f5bfef5a6ed92da482caa9568e5b6fe9d8a9ddd9eb09277b92cef9046efa18500944cbe800a0b1527ea64729a861d2f6497a3235c37f4192779ec1d96b3b1c5424fce0b727b030" + }, + { + "pubkey": "0x5125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00ce73bff706f7ff4b6f44090a32711f3208e4e", + "withdrawal_credentials": "0x078143ee26a586ad23139d5041723470bf24a865837c9123461c41f5ff99aa99", + "amount": "2408919902728845389", + "signature": "0xce24eb65491622558fdf297b9fa007864bafd7cd4ca1b2fb5766ab431a032b72b9a7e937ed648d0801f29055d3090d2463718254f9442483c7b98b938045da519843854b0ed3f7ba951a493f321f0966603022c1dfc579b99ed9d20d573ad531" + } + ] + } + ], + "signature_aggregate": "0x9347800979d1830356f2a54c3deab2a4b4475d63afbe8fb56987c77f5818526f", + "lock_hash": "0x3511c8de562186b1a95cb4fd73a30a26707cd05003e4050134254cb30f7e456e", + "node_signatures": [ + "0xb38b19f53784c19e9beac03c875a27db029de37ae37a42318813487685929359", + "0xca8c5eb94e152dc1af42ea3d1676c1bdd19ab8e2925c6daee4de5ef9f9dcf08d" + ] +} \ No newline at end of file diff --git a/cluster/version.go b/cluster/version.go index cd36cc975..8dcfeda4f 100644 --- a/cluster/version.go +++ b/cluster/version.go @@ -5,19 +5,20 @@ package cluster import "testing" const ( - currentVersion = v1_8 + currentVersion = v1_10 dkgAlgo = "default" - v1_9 = "v1.9.0" - v1_8 = "v1.8.0" // Default - 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" // Default + 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" zeroNonce = 0 @@ -25,16 +26,17 @@ const ( ) var supportedVersions = map[string]bool{ - v1_9: true, - v1_8: true, - v1_7: true, - v1_6: true, - v1_5: true, - v1_4: true, - v1_3: true, - v1_2: true, - v1_1: true, - v1_0: true, + v1_10: true, + v1_9: true, + v1_8: true, + v1_7: true, + v1_6: true, + v1_5: true, + v1_4: true, + v1_3: true, + v1_2: true, + v1_1: true, + v1_0: true, } func isAnyVersion(version string, versions ...string) bool { diff --git a/cmd/addvalidators.go b/cmd/addvalidators.go index 17edc90c6..9fc06de71 100644 --- a/cmd/addvalidators.go +++ b/cmd/addvalidators.go @@ -131,7 +131,7 @@ func runAddValidatorsSolo(ctx context.Context, conf addValidatorsConfig) (err er conf.WithdrawalAddrs = repeatAddr(conf.WithdrawalAddrs[0], conf.NumVals) } - vals, secrets, shareSets, err := genNewVals(len(cluster.GetOperators()), int(cluster.GetThreshold()), cluster.GetForkVersion(), conf) + vals, secrets, shareSets, err := genNewVals(ctx, len(cluster.GetOperators()), int(cluster.GetThreshold()), cluster.GetForkVersion(), cluster.GetTargetGasLimit(), conf) if err != nil { return err } @@ -203,16 +203,21 @@ func runAddValidatorsSolo(ctx context.Context, conf addValidatorsConfig) (err er } // builderRegistration returns a builder registration object using the provided inputs. -func builderRegistration(secret tbls.PrivateKey, pubkey tbls.PublicKey, feeRecipientAddr string, forkVersion []byte) (*eth2v1.SignedValidatorRegistration, error) { +func builderRegistration(ctx context.Context, secret tbls.PrivateKey, pubkey tbls.PublicKey, feeRecipientAddr string, forkVersion []byte, targetGasLimit uint32) (*eth2v1.SignedValidatorRegistration, error) { timestamp, err := eth2util.ForkVersionToGenesisTime(forkVersion) if err != nil { return nil, errors.Wrap(err, "invalid fork version") } + if targetGasLimit == 0 { + log.Warn(ctx, "", errors.New("custom target gas limit not supported, setting to default", z.Uint("default_gas_limit", registration.DefaultGasLimit))) + targetGasLimit = registration.DefaultGasLimit + } + reg, err := registration.NewMessage( eth2p0.BLSPubKey(pubkey), feeRecipientAddr, - registration.DefaultGasLimit, + uint64(targetGasLimit), timestamp, ) if err != nil { @@ -384,7 +389,7 @@ func validateConf(conf addValidatorsConfig) error { } // genNewVals returns a list of new validators, their corresponding private keys and threshold keyshares from the provided config. -func genNewVals(numOps, threshold int, forkVersion []byte, conf addValidatorsConfig) ([]*manifestpb.Validator, []tbls.PrivateKey, [][]tbls.PrivateKey, error) { +func genNewVals(ctx context.Context, numOps, threshold int, forkVersion []byte, targetGasLimit uint32, conf addValidatorsConfig) ([]*manifestpb.Validator, []tbls.PrivateKey, [][]tbls.PrivateKey, error) { // Generate new validators var ( vals []*manifestpb.Validator @@ -439,7 +444,7 @@ func genNewVals(numOps, threshold int, forkVersion []byte, conf addValidatorsCon } // Generate builder registration - builderReg, err := builderRegistration(secret, pubkey, feeRecipientAddr, forkVersion) + builderReg, err := builderRegistration(ctx, secret, pubkey, feeRecipientAddr, forkVersion, targetGasLimit) if err != nil { return nil, nil, nil, err } diff --git a/cmd/createcluster.go b/cmd/createcluster.go index 14229f206..2be1eec06 100644 --- a/cmd/createcluster.go +++ b/cmd/createcluster.go @@ -83,6 +83,8 @@ type clusterConfig struct { ConsensusProtocol string + TargetGasLimit uint + testnetConfig eth2util.Network } @@ -143,6 +145,7 @@ func bindClusterFlags(flags *pflag.FlagSet, config *clusterConfig) { flags.Int64Var(&config.testnetConfig.GenesisTimestamp, "testnet-genesis-timestamp", 0, "Genesis timestamp of the custom test network.") flags.IntSliceVar(&config.DepositAmounts, "deposit-amounts", nil, "List of partial deposit amounts (integers) in ETH. Values must sum up to exactly 32ETH.") flags.StringVar(&config.ConsensusProtocol, "consensus-protocol", "", "Preferred consensus protocol name for the cluster. Selected automatically when not specified.") + flags.UintVar(&config.TargetGasLimit, "target-gas-limit", 36000000, "Preferred target gas limit for transactions.") } func bindInsecureFlags(flags *pflag.FlagSet, insecureKeys *bool) { @@ -276,7 +279,7 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro return err } - valRegs, err := createValidatorRegistrations(def.FeeRecipientAddresses(), secrets, def.ForkVersion, conf.SplitKeys) + valRegs, err := createValidatorRegistrations(ctx, def.FeeRecipientAddresses(), secrets, def.ForkVersion, conf.SplitKeys, conf.TargetGasLimit) if err != nil { return err } @@ -469,7 +472,7 @@ func signDepositDatas(secrets []tbls.PrivateKey, withdrawalAddresses []string, n } // signValidatorRegistrations returns a slice of validator registrations for each private key in secrets. -func signValidatorRegistrations(secrets []tbls.PrivateKey, feeAddresses []string, forkVersion []byte, useCurrentTimestamp bool) ([]core.VersionedSignedValidatorRegistration, error) { +func signValidatorRegistrations(secrets []tbls.PrivateKey, feeAddresses []string, forkVersion []byte, useCurrentTimestamp bool, targetGasLimit uint) ([]core.VersionedSignedValidatorRegistration, error) { if len(secrets) != len(feeAddresses) { return nil, errors.New("insufficient fee addresses") } @@ -500,7 +503,7 @@ func signValidatorRegistrations(secrets []tbls.PrivateKey, feeAddresses []string unsignedReg, err := registration.NewMessage( eth2p0.BLSPubKey(pk), feeAddress, - registration.DefaultGasLimit, + uint64(targetGasLimit), timestamp, ) if err != nil { @@ -621,12 +624,17 @@ func createDepositDatas(withdrawalAddresses []string, network string, secrets [] } // createValidatorRegistrations creates a slice of builder validator registrations using the provided parameters and returns it. -func createValidatorRegistrations(feeAddresses []string, secrets []tbls.PrivateKey, forkVersion []byte, useCurrentTimestamp bool) ([]core.VersionedSignedValidatorRegistration, error) { +func createValidatorRegistrations(ctx context.Context, feeAddresses []string, secrets []tbls.PrivateKey, forkVersion []byte, useCurrentTimestamp bool, targetGasLimit uint) ([]core.VersionedSignedValidatorRegistration, error) { if len(feeAddresses) != len(secrets) { return nil, errors.New("insufficient fee addresses") } - return signValidatorRegistrations(secrets, feeAddresses, forkVersion, useCurrentTimestamp) + if targetGasLimit == 0 { + log.Warn(ctx, "", errors.New("custom target gas limit not supported, setting to default", z.Uint("default_gas_limit", registration.DefaultGasLimit))) + targetGasLimit = registration.DefaultGasLimit + } + + return signValidatorRegistrations(secrets, feeAddresses, forkVersion, useCurrentTimestamp, targetGasLimit) } // writeLock creates a cluster lock and writes it to disk for all peers. @@ -851,12 +859,9 @@ func newDefFromConfig(ctx context.Context, conf clusterConfig) (cluster.Definiti threshold := safeThreshold(ctx, conf.NumNodes, conf.Threshold) var opts []func(*cluster.Definition) - if len(conf.DepositAmounts) > 0 { - opts = append(opts, cluster.WithVersion(cluster.MinVersionForPartialDeposits)) - } def, err := cluster.NewDefinition(conf.Name, conf.NumDVs, threshold, feeRecipientAddrs, withdrawalAddrs, forkVersion, cluster.Creator{}, ops, conf.DepositAmounts, - conf.ConsensusProtocol, rand.Reader, opts...) + conf.ConsensusProtocol, conf.TargetGasLimit, rand.Reader, opts...) if err != nil { return cluster.Definition{}, err } diff --git a/cmd/createcluster_internal_test.go b/cmd/createcluster_internal_test.go index 46a09fc8d..ccc0dabdc 100644 --- a/cmd/createcluster_internal_test.go +++ b/cmd/createcluster_internal_test.go @@ -35,7 +35,7 @@ import ( //go:generate go test . -run=TestCreateCluster -update func TestCreateCluster(t *testing.T) { - defPath := "../cluster/examples/cluster-definition-005.json" + defPath := "../cluster/examples/cluster-definition-006.json" def, err := loadDefinition(context.Background(), defPath) require.NoError(t, err) @@ -224,7 +224,7 @@ func TestCreateCluster(t *testing.T) { NumNodes: 3, Threshold: 3, NumDVs: 5, - Network: "goerli", + Network: eth2util.Goerli.Name, }, Prep: func(t *testing.T, config clusterConfig) clusterConfig { t.Helper() @@ -269,7 +269,7 @@ func TestCreateCluster(t *testing.T) { NumNodes: 2, Threshold: 2, NumDVs: 1, - Network: "goerli", + Network: eth2util.Goerli.Name, }, defFileProvider: func() []byte { data, err := json.Marshal(defTwoNodes) @@ -279,6 +279,17 @@ func TestCreateCluster(t *testing.T) { }, expectedErr: "number of operators is below minimum", }, + { + Name: "custom target gas limit", + Config: clusterConfig{ + Name: "test_cluster", + NumNodes: 4, + Threshold: 3, + NumDVs: 3, + Network: eth2util.Holesky.Name, + TargetGasLimit: 36000000, + }, + }, } for _, test := range tests { @@ -297,6 +308,9 @@ func TestCreateCluster(t *testing.T) { test.Config.InsecureKeys = true test.Config.WithdrawalAddrs = []string{zeroAddress} test.Config.FeeRecipientAddrs = []string{zeroAddress} + if test.Config.TargetGasLimit == 0 && test.defFileProvider == nil { + test.Config.TargetGasLimit = 30000000 + } if test.Prep != nil { test.Config = test.Prep(t, test.Config) @@ -417,11 +431,12 @@ func testCreateCluster(t *testing.T, conf clusterConfig, def cluster.Definition, func TestValidateDef(t *testing.T) { ctx := context.Background() conf := clusterConfig{ - Name: "test", - NumNodes: 4, - NumDVs: 4, - Threshold: 3, - Network: "goerli", + Name: "test", + NumNodes: 4, + NumDVs: 4, + Threshold: 3, + TargetGasLimit: 30000000, + Network: eth2util.Goerli.Name, } for range conf.NumDVs { @@ -568,6 +583,7 @@ func TestSplitKeys(t *testing.T) { test.conf.SplitKeys = true test.conf.InsecureKeys = true test.conf.Network = eth2util.Goerli.Name + test.conf.TargetGasLimit = 30000000 var buf bytes.Buffer err = runCreateCluster(context.Background(), &buf, test.conf) @@ -640,6 +656,90 @@ func TestMultipleAddresses(t *testing.T) { }) } +func TestTargetGasLimit(t *testing.T) { + tests := []struct { + name string + conf clusterConfig + expectedTargetGasLimit uint + expectedErrMsg string + }{ + { + name: "target gas limit from unsupported version", + conf: clusterConfig{ + DefFile: "../cluster/examples/cluster-definition-005.json", + ClusterDir: t.TempDir(), + NumNodes: 4, + Network: defaultNetwork, + }, + expectedTargetGasLimit: 0, + }, + { + name: "target gas limit from supported version", + conf: clusterConfig{ + DefFile: "../cluster/examples/cluster-definition-006.json", + ClusterDir: t.TempDir(), + NumNodes: 4, + Network: defaultNetwork, + }, + expectedTargetGasLimit: 30000000, + }, + { + name: "target gas limit with default version", + conf: clusterConfig{ + Name: t.Name(), + ClusterDir: t.TempDir(), + NumNodes: 4, + Threshold: 3, + NumDVs: 1, + Network: defaultNetwork, + WithdrawalAddrs: []string{zeroAddress}, + FeeRecipientAddrs: []string{zeroAddress}, + InsecureKeys: true, + TargetGasLimit: 36000000, + }, + expectedTargetGasLimit: 36000000, + }, + { + name: "no target gas limit with default version", + conf: clusterConfig{ + Name: t.Name(), + ClusterDir: t.TempDir(), + NumNodes: 4, + Threshold: 3, + NumDVs: 1, + Network: defaultNetwork, + WithdrawalAddrs: []string{zeroAddress}, + FeeRecipientAddrs: []string{zeroAddress}, + InsecureKeys: true, + }, + expectedErrMsg: "target gas limit should be set", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var buf bytes.Buffer + err := runCreateCluster(context.Background(), &buf, test.conf) + if test.expectedErrMsg != "" { + require.ErrorContains(t, err, test.expectedErrMsg) + } else { + testutil.RequireNoError(t, err) + + // Since `cluster-lock.json` is copied into each node directory, use any one of them. + b, err := os.ReadFile(path.Join(nodeDir(test.conf.ClusterDir, 0), "cluster-lock.json")) + require.NoError(t, err) + + var lock cluster.Lock + require.NoError(t, json.Unmarshal(b, &lock)) + require.NoError(t, lock.VerifyHashes()) + require.NoError(t, lock.VerifySignatures()) + + require.Equal(t, test.expectedTargetGasLimit, lock.TargetGasLimit) + } + }) + } +} + // TestKeymanager tests keymanager support by letting create cluster command split a single secret and then receiving those keyshares using test // keymanager servers. These shares are then combined to create the combined share which is then compared to the original secret that was split. func TestKeymanager(t *testing.T) { @@ -683,6 +783,7 @@ func TestKeymanager(t *testing.T) { SplitKeys: true, NumNodes: minNodes, Threshold: minThreshold, + TargetGasLimit: 30000000, KeymanagerAddrs: addrs, KeymanagerAuthTokens: authTokens, Network: eth2util.Goerli.Name, @@ -766,6 +867,7 @@ func TestPublish(t *testing.T) { NumNodes: minNodes, Threshold: minThreshold, NumDVs: 1, + TargetGasLimit: 30000000, Network: eth2util.Goerli.Name, WithdrawalAddrs: []string{zeroAddress}, FeeRecipientAddrs: []string{zeroAddress}, diff --git a/cmd/createdkg.go b/cmd/createdkg.go index 41923d594..8b66c06e2 100644 --- a/cmd/createdkg.go +++ b/cmd/createdkg.go @@ -34,6 +34,7 @@ type createDKGConfig struct { DepositAmounts []int // Amounts specified in ETH (integers). OperatorENRs []string ConsensusProtocol string + TargetGasLimit uint } func newCreateDKGCmd(runFunc func(context.Context, createDKGConfig) error) *cobra.Command { @@ -84,6 +85,7 @@ func bindCreateDKGFlags(cmd *cobra.Command, config *createDKGConfig) { cmd.Flags().IntSliceVar(&config.DepositAmounts, "deposit-amounts", nil, "List of partial deposit amounts (integers) in ETH. Values must sum up to exactly 32ETH.") cmd.Flags().StringSliceVar(&config.OperatorENRs, operatorENRs, nil, "[REQUIRED] Comma-separated list of each operator's Charon ENR address.") cmd.Flags().StringVar(&config.ConsensusProtocol, "consensus-protocol", "", "Preferred consensus protocol name for the cluster. Selected automatically when not specified.") + cmd.Flags().UintVar(&config.TargetGasLimit, "target-gas-limit", 36000000, "Preferred target gas limit for transactions.") mustMarkFlagRequired(cmd, operatorENRs) } @@ -144,14 +146,11 @@ func runCreateDKG(ctx context.Context, conf createDKGConfig) (err error) { var opts []func(*cluster.Definition) opts = append(opts, cluster.WithDKGAlgorithm(conf.DKGAlgo)) - if len(conf.DepositAmounts) > 0 { - opts = append(opts, cluster.WithVersion(cluster.MinVersionForPartialDeposits)) - } def, err := cluster.NewDefinition( conf.Name, conf.NumValidators, conf.Threshold, conf.FeeRecipientAddrs, conf.WithdrawalAddrs, forkVersion, cluster.Creator{}, operators, conf.DepositAmounts, - conf.ConsensusProtocol, crand.Reader, opts...) + conf.ConsensusProtocol, conf.TargetGasLimit, crand.Reader, opts...) if err != nil { return err } diff --git a/cmd/createdkg_internal_test.go b/cmd/createdkg_internal_test.go index c1a9dcfc6..a94bada79 100644 --- a/cmd/createdkg_internal_test.go +++ b/cmd/createdkg_internal_test.go @@ -30,6 +30,7 @@ func TestCreateDkgValid(t *testing.T) { DKGAlgo: "default", DepositAmounts: []int{8, 16, 4, 4}, ConsensusProtocol: "qbft", + TargetGasLimit: 30000000, OperatorENRs: []string{ "enr:-JG4QFI0llFYxSoTAHm24OrbgoVx77dL6Ehl1Ydys39JYoWcBhiHrRhtGXDTaygWNsEWFb1cL7a1Bk0klIdaNuXplKWGAYGv0Gt7gmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQL6bcis0tFXnbqG4KuywxT5BLhtmijPFApKCDJNl3mXFYN0Y3CCDhqDdWRwgg4u", "enr:-JG4QPnqHa7FU3PBqGxpV5L0hjJrTUqv8Wl6_UTHt-rELeICWjvCfcVfwmax8xI_eJ0ntI3ly9fgxAsmABud6-yBQiuGAYGv0iYPgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQMLLCMZ5Oqi_sdnBfdyhmysZMfFm78PgF7Y9jitTJPSroN0Y3CCPoODdWRwgj6E", diff --git a/cmd/testdata/TestCreateCluster_custom_target_gas_limit_files.golden b/cmd/testdata/TestCreateCluster_custom_target_gas_limit_files.golden new file mode 100644 index 000000000..153b92536 --- /dev/null +++ b/cmd/testdata/TestCreateCluster_custom_target_gas_limit_files.golden @@ -0,0 +1,22 @@ +[ + "node0", + "node1", + "node2", + "node3", + "node0/charon-enr-private-key", + "node0/cluster-lock.json", + "node0/deposit-data.json", + "node0/validator_keys", + "node1/charon-enr-private-key", + "node1/cluster-lock.json", + "node1/deposit-data.json", + "node1/validator_keys", + "node2/charon-enr-private-key", + "node2/cluster-lock.json", + "node2/deposit-data.json", + "node2/validator_keys", + "node3/charon-enr-private-key", + "node3/cluster-lock.json", + "node3/deposit-data.json", + "node3/validator_keys" +] \ No newline at end of file diff --git a/cmd/testdata/TestCreateCluster_custom_target_gas_limit_output.golden b/cmd/testdata/TestCreateCluster_custom_target_gas_limit_output.golden new file mode 100644 index 000000000..da2d5e3d2 --- /dev/null +++ b/cmd/testdata/TestCreateCluster_custom_target_gas_limit_output.golden @@ -0,0 +1,11 @@ +Created charon cluster: + --split-existing-keys=false + +charon/ +├─ node[0-3]/ Directory for each node +│ ├─ charon-enr-private-key Charon networking private key for node authentication +│ ├─ cluster-lock.json Cluster lock defines the cluster lock file which is signed by all nodes +│ ├─ deposit-data-*.json Deposit data files are used to activate a Distributed Validator on the DV Launchpad +│ ├─ validator_keys Validator keystores and password +│ │ ├─ keystore-*.json Validator private share key for duty signing +│ │ ├─ keystore-*.txt Keystore password files for keystore-*.json diff --git a/cmd/testdata/Test_viewClusterManifest.golden b/cmd/testdata/Test_viewClusterManifest.golden index 0d6d1eca5..1c91e7b80 100644 --- a/cmd/testdata/Test_viewClusterManifest.golden +++ b/cmd/testdata/Test_viewClusterManifest.golden @@ -1,8 +1,8 @@ { "dkg_algorithm": "default", "fork_version": "0x00001020", - "initial_mutation_hash": "0xa308b53642d9a244f40aac844e31cd8e4a3bdfb6f701d930195113748dacefeb", - "latest_mutation_hash": "0xa308b53642d9a244f40aac844e31cd8e4a3bdfb6f701d930195113748dacefeb", + "initial_mutation_hash": "0xe8183d11c7c648386b8e87fc5dbe61207a1b3a1581b191ecf76723da6d796ce5", + "latest_mutation_hash": "0xe8183d11c7c648386b8e87fc5dbe61207a1b3a1581b191ecf76723da6d796ce5", "name": "test cluster", "operators": [ { diff --git a/core/validatorapi/validatorapi.go b/core/validatorapi/validatorapi.go index 49a86eb53..863127719 100644 --- a/core/validatorapi/validatorapi.go +++ b/core/validatorapi/validatorapi.go @@ -33,8 +33,8 @@ import ( ) const ( - gasLimit = 30000000 - zeroAddress = "0x0000000000000000000000000000000000000000" + defaultGasLimit = 30000000 + zeroAddress = "0x0000000000000000000000000000000000000000" ) // SlotFromTimestamp returns the Ethereum slot associated to a timestamp, given the genesis configuration fetched @@ -86,7 +86,7 @@ func NewComponentInsecure(_ *testing.T, eth2Cl eth2wrap.Client, shareIdx int) (* // NewComponent returns a new instance of the validator API core workflow component. func NewComponent(eth2Cl eth2wrap.Client, allPubSharesByKey map[core.PubKey]map[int]tbls.PublicKey, - shareIdx int, feeRecipientFunc func(core.PubKey) string, builderEnabled bool, seenPubkeys func(core.PubKey), + shareIdx int, feeRecipientFunc func(core.PubKey) string, builderEnabled bool, targetGasLimit uint, seenPubkeys func(core.PubKey), ) (*Component, error) { var ( sharesByKey = make(map[eth2p0.BLSPubKey]eth2p0.BLSPubKey) @@ -168,6 +168,7 @@ func NewComponent(eth2Cl eth2wrap.Client, allPubSharesByKey map[core.PubKey]map[ shareIdx: shareIdx, feeRecipientFunc: feeRecipientFunc, builderEnabled: builderEnabled, + targetGasLimit: targetGasLimit, swallowRegFilter: log.Filter(), }, nil } @@ -178,6 +179,7 @@ type Component struct { insecureTest bool feeRecipientFunc func(core.PubKey) string builderEnabled bool + targetGasLimit uint swallowRegFilter z.Field // getVerifyShareFunc maps public shares (what the VC thinks as its public key) @@ -1276,13 +1278,20 @@ func (c Component) getAggregateSyncCommSelection(ctx context.Context, psigsBySlo // ProposerConfig returns the proposer configuration for all validators. func (c Component) ProposerConfig(ctx context.Context) (*eth2exp.ProposerConfigResponse, error) { + var targetGasLimit uint + if c.targetGasLimit == 0 { + log.Warn(ctx, "", errors.New("custom target gas limit not supported, setting to default", z.Uint("default_gas_limit", defaultGasLimit))) + targetGasLimit = defaultGasLimit + } else { + targetGasLimit = c.targetGasLimit + } resp := eth2exp.ProposerConfigResponse{ Proposers: make(map[eth2p0.BLSPubKey]eth2exp.ProposerConfig), Default: eth2exp.ProposerConfig{ // Default doesn't make sense, disable for now. FeeRecipient: zeroAddress, Builder: eth2exp.Builder{ Enabled: false, - GasLimit: gasLimit, + GasLimit: targetGasLimit, }, }, } @@ -1313,7 +1322,7 @@ func (c Component) ProposerConfig(ctx context.Context) (*eth2exp.ProposerConfigR FeeRecipient: c.feeRecipientFunc(pubkey), Builder: eth2exp.Builder{ Enabled: c.builderEnabled, - GasLimit: gasLimit, + GasLimit: targetGasLimit, Overrides: map[string]string{ "timestamp": strconv.FormatInt(timestamp.Unix(), 10), "public_key": string(pubkey), diff --git a/core/validatorapi/validatorapi_internal_test.go b/core/validatorapi/validatorapi_internal_test.go index 1d5ceda69..990c5accc 100644 --- a/core/validatorapi/validatorapi_internal_test.go +++ b/core/validatorapi/validatorapi_internal_test.go @@ -31,7 +31,7 @@ func TestMismatchKeysFunc(t *testing.T) { t.Run("no mismatch", func(t *testing.T) { allPubSharesByKey := map[core.PubKey]map[int]tbls.PublicKey{corePubKey: {shareIdx: pubkey}} // Maps self to self since not tbls - vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, defaultGasLimit, nil) require.NoError(t, err) pk, err := vapi.getPubKeyFunc(eth2Pubkey) require.NoError(t, err) @@ -47,7 +47,7 @@ func TestMismatchKeysFunc(t *testing.T) { pubshare := *(*tbls.PublicKey)(pkb) allPubSharesByKey := map[core.PubKey]map[int]tbls.PublicKey{corePubKey: {shareIdx: pubkey, shareIdx + 1: pubshare}} - vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, defaultGasLimit, nil) require.NoError(t, err) resp, err := vapi.getPubKeyFunc(eth2p0.BLSPubKey(pubshare)) // Ask for a mismatching key @@ -65,7 +65,7 @@ func TestMismatchKeysFunc(t *testing.T) { pubshare := eth2p0.BLSPubKey(pk) allPubSharesByKey := map[core.PubKey]map[int]tbls.PublicKey{corePubKey: {shareIdx: pubkey}} - vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := NewComponent(nil, allPubSharesByKey, shareIdx, nil, false, defaultGasLimit, nil) require.NoError(t, err) _, err = vapi.getPubKeyFunc(pubshare) // Ask for a mismatching key diff --git a/core/validatorapi/validatorapi_test.go b/core/validatorapi/validatorapi_test.go index d5304b491..1a03ef0d2 100644 --- a/core/validatorapi/validatorapi_test.go +++ b/core/validatorapi/validatorapi_test.go @@ -192,7 +192,7 @@ func TestSubmitAttestations_Verify(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) vapi.RegisterPubKeyByAttestation(func(ctx context.Context, slot, commIdx, valCommIdx uint64) (core.PubKey, error) { @@ -300,7 +300,7 @@ func TestSignAndVerify(t *testing.T) { allPubSharesByKey := map[core.PubKey]map[int]tbls.PublicKey{corePubKey: {shareIdx: pubkey}} // Maps self to self since not tbls // Setup validatorapi component. - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) vapi.RegisterPubKeyByAttestation(func(context.Context, uint64, uint64, uint64) (core.PubKey, error) { return core.PubKeyFromBytes(pubkey[:]) @@ -436,7 +436,7 @@ func TestComponent_SubmitProposalsWithWrongVCData(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) t.Run("full block fails", func(t *testing.T) { @@ -534,7 +534,7 @@ func TestComponent_SubmitProposal(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) // Prepare unsigned beacon block @@ -628,7 +628,7 @@ func TestComponent_SubmitProposal_Gnosis(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) // Prepare unsigned beacon block @@ -725,7 +725,7 @@ func TestComponent_SubmitProposalInvalidSignature(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) // Prepare unsigned beacon block @@ -794,7 +794,7 @@ func TestComponent_SubmitProposalInvalidBlock(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) vapi.RegisterGetDutyDefinition(func(ctx context.Context, duty core.Duty) (core.DutyDefinitionSet, error) { @@ -919,7 +919,7 @@ func TestComponent_SubmitBlindedProposal(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, 30000000, nil) require.NoError(t, err) // Prepare unsigned beacon block @@ -1009,7 +1009,7 @@ func TestComponent_SubmitBlindedProposalInvalidSignature(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, 30000000, nil) require.NoError(t, err) // Prepare unsigned beacon block @@ -1083,7 +1083,7 @@ func TestComponent_SubmitBlindedProposalInvalidBlock(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, 30000000, nil) require.NoError(t, err) vapi.RegisterGetDutyDefinition(func(ctx context.Context, duty core.Duty) (core.DutyDefinitionSet, error) { @@ -1211,7 +1211,7 @@ func TestComponent_SubmitVoluntaryExit(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) // Prepare unsigned voluntary exit @@ -1281,7 +1281,7 @@ func TestComponent_SubmitVoluntaryExitInvalidSignature(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) // Register subscriber @@ -1337,7 +1337,7 @@ func TestComponent_Duties(t *testing.T) { } // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) opts := ð2api.ProposerDutiesOpts{ @@ -1363,7 +1363,7 @@ func TestComponent_Duties(t *testing.T) { } // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) opts := ð2api.AttesterDutiesOpts{ @@ -1389,7 +1389,7 @@ func TestComponent_Duties(t *testing.T) { } // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) opts := ð2api.SyncCommitteeDutiesOpts{ @@ -1425,7 +1425,7 @@ func TestComponent_SubmitValidatorRegistration(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, 30000000, nil) require.NoError(t, err) unsigned := testutil.RandomValidatorRegistration(t) @@ -1503,7 +1503,7 @@ func TestComponent_SubmitValidatorRegistrationInvalidSignature(t *testing.T) { require.NoError(t, err) // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, true, 30000000, nil) require.NoError(t, err) unsigned := testutil.RandomValidatorRegistration(t) @@ -1558,7 +1558,7 @@ func TestComponent_TekuProposerConfig(t *testing.T) { // Construct the validator api component vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, func(core.PubKey) string { return feeRecipient - }, true, nil) + }, true, 30000000, nil) require.NoError(t, err) resp, err := vapi.ProposerConfig(ctx) @@ -1727,7 +1727,7 @@ func TestComponent_SubmitAggregateAttestationVerify(t *testing.T) { } // Construct the validator api component - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) done := make(chan struct{}) @@ -1859,7 +1859,7 @@ func TestComponent_SubmitSyncCommitteeContributionsVerify(t *testing.T) { } // Construct validatorapi component. - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) done := make(chan struct{}) @@ -1941,7 +1941,7 @@ func TestComponent_ValidatorCache(t *testing.T) { } } - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, 1, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, 1, nil, false, 30000000, nil) require.NoError(t, err) // request validators that are completely cached @@ -2013,7 +2013,7 @@ func TestComponent_GetAllValidators(t *testing.T) { require.NoError(t, err) // Construct validatorapi component. - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) opts := ð2api.ValidatorsOpts{ @@ -2050,7 +2050,7 @@ func TestComponent_GetClusterValidatorsWithError(t *testing.T) { require.NoError(t, err) // Construct validatorapi component. - vapi, err := validatorapi.NewComponent(bmock, make(map[core.PubKey]map[int]tbls.PublicKey), shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, make(map[core.PubKey]map[int]tbls.PublicKey), shareIdx, nil, false, 30000000, nil) require.NoError(t, err) opts := ð2api.ValidatorsOpts{ @@ -2127,7 +2127,7 @@ func TestComponent_AggregateSyncCommitteeSelectionsVerify(t *testing.T) { } // Construct the validator api component. - vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, nil) + vapi, err := validatorapi.NewComponent(bmock, allPubSharesByKey, shareIdx, nil, false, 30000000, nil) require.NoError(t, err) vapi.RegisterAwaitAggSigDB(func(ctx context.Context, duty core.Duty, pubkey core.PubKey) (core.SignedData, error) { diff --git a/dkg/dkg.go b/dkg/dkg.go index ee890dde4..23dd97528 100644 --- a/dkg/dkg.go +++ b/dkg/dkg.go @@ -111,7 +111,7 @@ func Run(ctx context.Context, conf Config) (err error) { } // This DKG only supports a few specific config versions. - if def.Version != "v1.6.0" && def.Version != "v1.7.0" && def.Version != "v1.8.0" { + if def.Version != "v1.6.0" && def.Version != "v1.7.0" && def.Version != "v1.8.0" && def.Version != "v1.9.0" && def.Version != "v1.10.0" { return errors.New("only v1.6.0, v1.7.0 and v1.8.0 cluster definition versions supported") } @@ -267,7 +267,7 @@ func Run(ctx context.Context, conf Config) (err error) { ex, shares, def.FeeRecipientAddresses(), - registration.DefaultGasLimit, + uint64(def.TargetGasLimit), nodeIdx, def.ForkVersion, ) @@ -638,11 +638,16 @@ func signAndAggValidatorRegistrations( ex *exchanger, shares []share, feeRecipients []string, - gasLimit uint64, + targetGasLimit uint64, nodeIdx cluster.NodeIdx, forkVersion []byte, ) ([]core.VersionedSignedValidatorRegistration, error) { - parSig, valRegs, err := signValidatorRegistrations(shares, nodeIdx.ShareIdx, feeRecipients, gasLimit, forkVersion) + if targetGasLimit == 0 { + log.Warn(ctx, "", errors.New("custom target gas limit not supported, setting to default", z.Uint("default_gas_limit", registration.DefaultGasLimit))) + targetGasLimit = registration.DefaultGasLimit + } + + parSig, valRegs, err := signValidatorRegistrations(shares, nodeIdx.ShareIdx, feeRecipients, targetGasLimit, forkVersion) if err != nil { return nil, err } diff --git a/dkg/dkg_test.go b/dkg/dkg_test.go index 44c161813..2a74566f9 100644 --- a/dkg/dkg_test.go +++ b/dkg/dkg_test.go @@ -42,6 +42,30 @@ import ( "github.com/obolnetwork/charon/testutil" ) +const ( + 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" +) + +func isAnyVersion(version string, list ...string) bool { + for _, v := range list { + if version == v { + return true + } + } + + return false +} + func TestDKG(t *testing.T) { const ( nodes = 3 @@ -108,6 +132,11 @@ func TestDKG(t *testing.T) { if test.version != "" { opts = append(opts, cluster.WithVersion(test.version)) } + if isAnyVersion(test.version, v1_0, v1_1, v1_2, v1_3, v1_4, v1_5, v1_6, v1_7, v1_8, v1_9) { + opts = append(opts, func(d *cluster.Definition) { d.TargetGasLimit = 0 }) + } else { + opts = append(opts, func(d *cluster.Definition) { d.TargetGasLimit = 30000000 }) + } seed := 1 random := rand.New(rand.NewSource(int64(seed)))