Skip to content

Commit 823f947

Browse files
committed
add many validator parallel test
1 parent b8b6df7 commit 823f947

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

signer/sign_attestation_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package signer
33
import (
44
"encoding/hex"
55
"fmt"
6+
"sync"
67
"testing"
78
"time"
89

@@ -134,6 +135,117 @@ func TestLockSameValidatorInParallel(t *testing.T) {
134135

135136
}
136137

138+
func TestManyValidatorsParallel(t *testing.T) {
139+
type testValidator struct {
140+
sk []byte
141+
pk []byte
142+
id string
143+
}
144+
145+
testValidators := []testValidator{
146+
{
147+
sk: _byteArray("2c083f2c8fc923fa2bd32a70ab72b4b46247e8c1f347adc30b2f8036a355086c"),
148+
pk: _byteArray("a9cf360aa15fb1d1d30ee2b578dc5884823c19661886ae8b892775ccb3bd96b7d7345569a2aa0b14e4d015c54a6a0c54"),
149+
id: "1",
150+
},
151+
{
152+
sk: _byteArray("6327b1e58c41d60dd7c3c8b9634204255707c2d12e2513c345001d8926745eea"),
153+
pk: _byteArray("954eb88ed1207f891dc3c28fa6cfdf8f53bf0ed3d838f3476c0900a61314d22d4f0a300da3cd010444dd5183e35a593c"),
154+
id: "2",
155+
},
156+
{
157+
sk: _byteArray("5470813f7deef638dc531188ca89e36976d536f680e89849cd9077fd096e20bc"),
158+
pk: _byteArray("a3862121db5914d7272b0b705e6e3c5336b79e316735661873566245207329c30f9a33d4fb5f5857fc6fd0a368186972"),
159+
id: "3",
160+
},
161+
}
162+
163+
attestationDataByts := _byteArray("000000000000000000000000000000003a43a4bf26fb5947e809c1f24f7dc6857c8ac007e535d48e6e4eca2122fd776b0000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000003a43a4bf26fb5947e809c1f24f7dc6857c8ac007e535d48e6e4eca2122fd776b")
164+
domain := _byteArray32("0100000081509579e35e84020ad8751eca180b44df470332d3ad17fc6fd52459")
165+
166+
// setup KeyVault
167+
store := inmemStorage()
168+
options := &eth2keymanager.KeyVaultOptions{}
169+
options.SetStorage(store)
170+
options.SetWalletType(core.NDWallet)
171+
vault, err := eth2keymanager.NewKeyVault(options)
172+
require.NoError(t, err)
173+
wallet, err := vault.Wallet()
174+
require.NoError(t, err)
175+
176+
// create accounts
177+
protector := prot.NewNormalProtection(store)
178+
for i := range testValidators {
179+
k, err := core.NewHDKeyFromPrivateKey(testValidators[i].sk, "")
180+
require.NoError(t, err)
181+
require.EqualValues(t, testValidators[i].pk, k.PublicKey().Serialize())
182+
183+
acc := wallets.NewValidatorAccount(testValidators[i].id, k, nil, "", vault.Context)
184+
require.NoError(t, err)
185+
require.EqualValues(t, testValidators[i].pk, acc.ValidatorPublicKey())
186+
require.NoError(t, wallet.AddValidatorAccount(acc))
187+
188+
// setup base attestation data
189+
baseAttData := &phase0.AttestationData{}
190+
require.NoError(t, baseAttData.UnmarshalSSZ(attestationDataByts))
191+
err = protector.UpdateHighestAttestation(acc.ValidatorPublicKey(), baseAttData)
192+
require.NoError(t, err)
193+
}
194+
195+
// setup signer
196+
signer := NewSimpleSigner(wallet, protector, core.PraterNetwork)
197+
198+
// Sign attestation in parallel.
199+
type validatorResult struct {
200+
signs int
201+
errs int
202+
}
203+
var validatorResults = map[string]*validatorResult{}
204+
var mu sync.Mutex
205+
for _, v := range testValidators {
206+
validatorResults[string(v.pk)] = &validatorResult{}
207+
}
208+
209+
var wg sync.WaitGroup
210+
const goroutinesPerValidator = 10
211+
for _, v := range testValidators {
212+
v := v
213+
for i := 0; i < goroutinesPerValidator; i++ {
214+
wg.Add(1)
215+
go func() {
216+
defer wg.Done()
217+
218+
// decode attestation to be signed
219+
attData := &phase0.AttestationData{}
220+
require.NoError(t, attData.UnmarshalSSZ(attestationDataByts))
221+
attData.Slot += phase0.Slot(core.PraterNetwork.SlotsPerEpoch())
222+
attData.Source.Epoch++
223+
attData.Target.Epoch++
224+
225+
_, _, err := signer.SignBeaconAttestation(attData, domain, v.pk)
226+
// require.EqualValues(t, sig, actualSig)
227+
228+
mu.Lock()
229+
defer mu.Unlock()
230+
if err != nil {
231+
validatorResults[string(v.pk)].errs++
232+
require.ErrorContains(t, err, "slashable attestation (HighestAttestationVote), not signing")
233+
} else {
234+
validatorResults[string(v.pk)].signs++
235+
}
236+
}()
237+
}
238+
}
239+
wg.Wait()
240+
241+
for pk, v := range validatorResults {
242+
t.Logf("pk: %x, signs: %d, errs: %d", []byte(pk), v.signs, v.errs)
243+
244+
require.Equal(t, 1, v.signs)
245+
require.Equal(t, goroutinesPerValidator-1, v.errs)
246+
}
247+
}
248+
137249
func TestAttestationSlashingSignatures(t *testing.T) {
138250
t.Run("valid attestation, sign using public key", func(t *testing.T) {
139251
seed, _ := hex.DecodeString("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff")

0 commit comments

Comments
 (0)