Skip to content

Commit 7bc2e32

Browse files
edwardmackqdm12timwu20
committed
feat(lib/babe): add check of types.ConfigData.SecondarySlots for disabling secondary verification (ChainSafe#1910)
* add check for types.ConfigData.SecondarySlots * Update lib/babe/verify.go Co-authored-by: Quentin McGaw <[email protected]> * update ok = false if !b.secondarySlots * stub test for secondary verification * add test to verify secondary digest * address PR comments * add err check * update pointers to fix tests * add tests for decoding * my wip * fix VRF encoding * update linter tags Co-authored-by: Quentin McGaw <[email protected]> Co-authored-by: Tim Wu <[email protected]>
1 parent 13c92ea commit 7bc2e32

File tree

3 files changed

+101
-23
lines changed

3 files changed

+101
-23
lines changed

dot/types/babe.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (d *EpochDataRaw) ToEpochData() (*EpochData, error) {
9494
type ConfigData struct {
9595
C1 uint64
9696
C2 uint64
97-
SecondarySlots byte // TODO: this is unused, will need to update BABE verifier to use this (#1863)
97+
SecondarySlots byte
9898
}
9999

100100
// GetSlotFromHeader returns the BABE slot from the given header

lib/babe/verify.go

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ import (
3131
// verifierInfo contains the information needed to verify blocks
3232
// it remains the same for an epoch
3333
type verifierInfo struct {
34-
authorities []types.Authority
35-
randomness Randomness
36-
threshold *common.Uint128
34+
authorities []types.Authority
35+
randomness Randomness
36+
threshold *common.Uint128
37+
secondarySlots bool
3738
}
3839

3940
// onDisabledInfo contains information about an authority that's been disabled at a certain
@@ -224,9 +225,10 @@ func (v *VerificationManager) getVerifierInfo(epoch uint64) (*verifierInfo, erro
224225
}
225226

226227
return &verifierInfo{
227-
authorities: epochData.Authorities,
228-
randomness: epochData.Randomness,
229-
threshold: threshold,
228+
authorities: epochData.Authorities,
229+
randomness: epochData.Randomness,
230+
threshold: threshold,
231+
secondarySlots: configData.SecondarySlots > 0,
230232
}, nil
231233
}
232234

@@ -247,11 +249,12 @@ func (v *VerificationManager) getConfigData(epoch uint64) (*types.ConfigData, er
247249

248250
// verifier is a BABE verifier for a specific authority set, randomness, and threshold
249251
type verifier struct {
250-
blockState BlockState
251-
epoch uint64
252-
authorities []types.Authority
253-
randomness Randomness
254-
threshold *common.Uint128
252+
blockState BlockState
253+
epoch uint64
254+
authorities []types.Authority
255+
randomness Randomness
256+
threshold *common.Uint128
257+
secondarySlots bool
255258
}
256259

257260
// newVerifier returns a Verifier for the epoch described by the given descriptor
@@ -261,11 +264,12 @@ func newVerifier(blockState BlockState, epoch uint64, info *verifierInfo) (*veri
261264
}
262265

263266
return &verifier{
264-
blockState: blockState,
265-
epoch: epoch,
266-
authorities: info.authorities,
267-
randomness: info.randomness,
268-
threshold: info.threshold,
267+
blockState: blockState,
268+
epoch: epoch,
269+
authorities: info.authorities,
270+
randomness: info.randomness,
271+
threshold: info.threshold,
272+
secondarySlots: info.secondarySlots,
269273
}, nil
270274
}
271275

@@ -409,15 +413,28 @@ func (b *verifier) verifyPreRuntimeDigest(digest *types.PreRuntimeDigest) (scale
409413
case types.BabePrimaryPreDigest:
410414
ok, err = b.verifyPrimarySlotWinner(d.AuthorityIndex, d.SlotNumber, d.VRFOutput, d.VRFProof)
411415
case types.BabeSecondaryVRFPreDigest:
416+
if !b.secondarySlots {
417+
ok = false
418+
break
419+
}
412420
pub := b.authorities[d.AuthorityIndex].Key
413-
var pk *sr25519.PublicKey
414-
pk, err = sr25519.NewPublicKey(pub.Encode())
421+
422+
pk, err := sr25519.NewPublicKey(pub.Encode())
415423
if err != nil {
416424
return nil, err
417425
}
418426

419427
ok, err = verifySecondarySlotVRF(&d, pk, b.epoch, len(b.authorities), b.randomness)
428+
if err != nil {
429+
return nil, err
430+
}
431+
420432
case types.BabeSecondaryPlainPreDigest:
433+
if !b.secondarySlots {
434+
ok = false
435+
break
436+
}
437+
421438
ok = true
422439
err = verifySecondarySlotPlain(d.AuthorityIndex, d.SlotNumber, len(b.authorities), b.randomness)
423440
}

lib/babe/verify_test.go

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@ package babe
1919
import (
2020
"errors"
2121
"io/ioutil"
22+
"math/big"
2223
"os"
2324
"testing"
2425
"time"
2526

26-
"github.com/ChainSafe/gossamer/lib/genesis"
27-
"github.com/stretchr/testify/require"
28-
2927
"github.com/ChainSafe/gossamer/dot/state"
3028
"github.com/ChainSafe/gossamer/dot/types"
29+
"github.com/ChainSafe/gossamer/lib/common"
3130
"github.com/ChainSafe/gossamer/lib/crypto/sr25519"
32-
31+
"github.com/ChainSafe/gossamer/lib/genesis"
32+
"github.com/ChainSafe/gossamer/pkg/scale"
3333
log "github.com/ChainSafe/log15"
34+
"github.com/stretchr/testify/require"
3435
)
3536

3637
func newTestVerificationManager(t *testing.T, genCfg *types.BabeConfiguration) *VerificationManager {
@@ -162,6 +163,66 @@ func TestVerificationManager_VerifyBlock_Ok(t *testing.T) {
162163
require.NoError(t, err)
163164
}
164165

166+
func TestVerificationManager_VerifyBlock_Secondary(t *testing.T) {
167+
babeService := createTestService(t, nil)
168+
rt, err := babeService.blockState.GetRuntime(nil)
169+
require.NoError(t, err)
170+
171+
cfg, err := rt.BabeConfiguration()
172+
require.NoError(t, err)
173+
174+
cfg.GenesisAuthorities = types.AuthoritiesToRaw(babeService.epochData.authorities)
175+
cfg.C1 = 1
176+
cfg.C2 = 1
177+
cfg.SecondarySlots = 0
178+
179+
vm := newTestVerificationManager(t, cfg)
180+
181+
kp, err := sr25519.GenerateKeypair()
182+
require.NoError(t, err)
183+
184+
dig := createSecondaryVRFPreDigest(t, kp, 0, uint64(0), uint64(0), Randomness{})
185+
186+
bd := types.NewBabeDigest()
187+
err = bd.Set(dig)
188+
require.NoError(t, err)
189+
190+
bdEnc, err := scale.Marshal(bd)
191+
require.NoError(t, err)
192+
193+
// create pre-digest
194+
preDigest := &types.PreRuntimeDigest{
195+
ConsensusEngineID: types.BabeEngineID,
196+
Data: bdEnc,
197+
}
198+
199+
// create new block header
200+
number := big.NewInt(1)
201+
digest := types.NewDigest()
202+
err = digest.Add(*preDigest)
203+
require.NoError(t, err)
204+
205+
// create seal and add to digest
206+
seal := &types.SealDigest{
207+
ConsensusEngineID: types.BabeEngineID,
208+
Data: []byte{0},
209+
}
210+
require.NoError(t, err)
211+
212+
err = digest.Add(*seal)
213+
require.NoError(t, err)
214+
215+
header, err := types.NewHeader(common.Hash{}, common.Hash{}, common.Hash{}, number, digest)
216+
require.NoError(t, err)
217+
218+
block := types.Block{
219+
Header: *header,
220+
Body: nil,
221+
}
222+
err = vm.VerifyBlock(&block.Header)
223+
require.EqualError(t, err, "failed to verify pre-runtime digest: could not verify slot claim VRF proof")
224+
}
225+
165226
func TestVerificationManager_VerifyBlock_MultipleEpochs(t *testing.T) {
166227
babeService := createTestService(t, nil)
167228
rt, err := babeService.blockState.GetRuntime(nil)

0 commit comments

Comments
 (0)