Skip to content

Commit 1f0a263

Browse files
add additional check to compare valid pubkeys to number of validator signing the message while handling validator registration event
1 parent 2f5e843 commit 1f0a263

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

rolling-shutter/keyperimpl/gnosis/validatorsyncer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ func (v *ValidatorSyncer) filterEvents(
202202
pubKeys = append(pubKeys, pubkey)
203203
}
204204

205+
if len(pubKeys) != len(msg.ValidatorIndices()) {
206+
evLog.Warn().Msg("ignoring registration message as the number of correct pubkeys does not match the number of validators")
207+
continue
208+
}
209+
205210
sig := new(blst.P2Affine).Uncompress(event.Signature)
206211
if sig == nil {
207212
evLog.Warn().Msg("ignoring registration message with undecodable signature")

rolling-shutter/keyperimpl/gnosis/validatorsyncer_test.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,127 @@ func TestAggregateValidatorRegisterFilterEvent(t *testing.T) {
121121
assert.DeepEqual(t, finalEvents, events)
122122
}
123123

124+
func TestValidatorRegisterWithInvalidNonce(t *testing.T) {
125+
if testing.Short() {
126+
t.Skip("skipping integration test")
127+
}
128+
msg := &validatorregistry.LegacyRegistrationMessage{
129+
Version: 0,
130+
ChainID: 2,
131+
ValidatorRegistryAddress: common.HexToAddress("0x1234567890123456789012345678901234567890"),
132+
ValidatorIndex: 3,
133+
Nonce: 1, // This nonce will be invalid
134+
IsRegistration: true,
135+
}
136+
ctx := context.Background()
137+
138+
var ikm [32]byte
139+
privkey := blst.KeyGen(ikm[:])
140+
pubkey := new(blst.P1Affine).From(privkey)
141+
142+
sig := validatorregistry.CreateSignature(privkey, msg)
143+
url := mockBeaconClient(t, hex.EncodeToString(pubkey.Compress()))
144+
145+
cl, err := beaconapiclient.New(url)
146+
assert.NilError(t, err)
147+
148+
dbpool, dbclose := testsetup.NewTestDBPool(ctx, t, database.Definition)
149+
t.Cleanup(dbclose)
150+
151+
// Insert a previous registration with a higher nonce
152+
db := database.New(dbpool)
153+
err = db.InsertValidatorRegistration(ctx, database.InsertValidatorRegistrationParams{
154+
BlockNumber: 1,
155+
BlockHash: []byte{1, 2, 3},
156+
TxIndex: 0,
157+
LogIndex: 0,
158+
ValidatorIndex: 3,
159+
Nonce: 2, // Higher nonce than the event
160+
IsRegistration: true,
161+
})
162+
assert.NilError(t, err)
163+
164+
vs := ValidatorSyncer{
165+
BeaconAPIClient: cl,
166+
DBPool: dbpool,
167+
ChainID: msg.ChainID,
168+
}
169+
170+
events := []*validatorRegistryBindings.ValidatorregistryUpdated{{
171+
Signature: sig.Compress(),
172+
Message: msg.Marshal(),
173+
Raw: types.Log{
174+
Address: common.HexToAddress("0x1234567890123456789012345678901234567890"),
175+
BlockNumber: 2,
176+
TxIndex: 0,
177+
Index: 0,
178+
},
179+
}}
180+
181+
finalEvents, err := vs.filterEvents(ctx, events)
182+
assert.NilError(t, err)
183+
184+
// The event should be filtered out due to invalid nonce
185+
assert.Equal(t, len(finalEvents), 0)
186+
}
187+
188+
func TestValidatorRegisterWithUnknownValidator(t *testing.T) {
189+
if testing.Short() {
190+
t.Skip("skipping integration test")
191+
}
192+
msg := &validatorregistry.LegacyRegistrationMessage{
193+
Version: 0,
194+
ChainID: 2,
195+
ValidatorRegistryAddress: common.HexToAddress("0x1234567890123456789012345678901234567890"),
196+
ValidatorIndex: 3,
197+
Nonce: 1,
198+
IsRegistration: true,
199+
}
200+
ctx := context.Background()
201+
202+
var ikm [32]byte
203+
privkey := blst.KeyGen(ikm[:])
204+
205+
sig := validatorregistry.CreateSignature(privkey, msg)
206+
207+
// Create a mock beacon client that returns not found for the validator
208+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
209+
w.WriteHeader(http.StatusNotFound)
210+
_, err := w.Write([]byte(`{"finalized": false, "data": null}`))
211+
assert.NilError(t, err)
212+
}))
213+
defer server.Close()
214+
215+
cl, err := beaconapiclient.New(server.URL)
216+
assert.NilError(t, err)
217+
218+
dbpool, dbclose := testsetup.NewTestDBPool(ctx, t, database.Definition)
219+
t.Cleanup(dbclose)
220+
221+
vs := ValidatorSyncer{
222+
BeaconAPIClient: cl,
223+
DBPool: dbpool,
224+
ChainID: msg.ChainID,
225+
}
226+
227+
events := []*validatorRegistryBindings.ValidatorregistryUpdated{{
228+
Signature: sig.Compress(),
229+
Message: msg.Marshal(),
230+
Raw: types.Log{
231+
Address: common.HexToAddress("0x1234567890123456789012345678901234567890"),
232+
BlockNumber: 2,
233+
TxIndex: 0,
234+
Index: 0,
235+
},
236+
}}
237+
238+
finalEvents, err := vs.filterEvents(ctx, events)
239+
assert.NilError(t, err)
240+
241+
// The event should be filtered out because the validator is unknown
242+
assert.Equal(t, len(finalEvents), 0)
243+
}
244+
124245
func mockBeaconClient(t *testing.T, pubKeyHex string) string {
125246
t.Helper()
126247
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)