Skip to content

Commit

Permalink
feat(lib/babe): Submit BABE equivocation report (#2947)
Browse files Browse the repository at this point in the history
- Added support for runtime functions `BabeGenerateKeyOwnershipProof` and `BabeSubmitReportEquivocationUnsignedExtrinsic`
- and report a babe equivocation report when it occurs

Issue #2853
  • Loading branch information
kishansagathiya authored Jan 26, 2023
1 parent 83b3278 commit 55de62e
Show file tree
Hide file tree
Showing 23 changed files with 1,054 additions and 103 deletions.
6 changes: 6 additions & 0 deletions dot/core/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ type RuntimeInstance interface {
DecodeSessionKeys(enc []byte) ([]byte, error)
PaymentQueryInfo(ext []byte) (*types.RuntimeDispatchInfo, error)
CheckInherents()
BabeGenerateKeyOwnershipProof(slot uint64, authorityID [32]byte) (
types.OpaqueKeyOwnershipProof, error)
BabeSubmitReportEquivocationUnsignedExtrinsic(
equivocationProof types.BabeEquivocationProof,
keyOwnershipProof types.OpaqueKeyOwnershipProof,
) error
RandomSeed()
OffchainWorker()
GenerateSessionKeys()
Expand Down
29 changes: 29 additions & 0 deletions dot/core/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dot/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type runtimeInterface interface {
DecodeSessionKeys(enc []byte) ([]byte, error)
PaymentQueryInfo(ext []byte) (*types.RuntimeDispatchInfo, error)
CheckInherents()
BabeGenerateKeyOwnershipProof(slot uint64, offenderPublicKey [32]byte) (types.OpaqueKeyOwnershipProof, error)
BabeSubmitReportEquivocationUnsignedExtrinsic(types.BabeEquivocationProof, types.OpaqueKeyOwnershipProof) error
RandomSeed()
OffchainWorker()
GenerateSessionKeys()
Expand Down
2 changes: 2 additions & 0 deletions dot/rpc/modules/interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type Runtime interface {
ExecuteBlock(block *types.Block) ([]byte, error)
DecodeSessionKeys(enc []byte) ([]byte, error)
PaymentQueryInfo(ext []byte) (*types.RuntimeDispatchInfo, error)
BabeGenerateKeyOwnershipProof(slot uint64, offenderPublicKey [32]byte) (types.OpaqueKeyOwnershipProof, error)
BabeSubmitReportEquivocationUnsignedExtrinsic(types.BabeEquivocationProof, types.OpaqueKeyOwnershipProof) error
CheckInherents()
RandomSeed()
OffchainWorker()
Expand Down
2 changes: 2 additions & 0 deletions dot/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ type Runtime interface {
DecodeSessionKeys(enc []byte) ([]byte, error)
PaymentQueryInfo(ext []byte) (*types.RuntimeDispatchInfo, error)
CheckInherents()
BabeGenerateKeyOwnershipProof(slot uint64, offenderPublicKey [32]byte) (types.OpaqueKeyOwnershipProof, error)
BabeSubmitReportEquivocationUnsignedExtrinsic(types.BabeEquivocationProof, types.OpaqueKeyOwnershipProof) error
RandomSeed()
OffchainWorker()
GenerateSessionKeys()
Expand Down
29 changes: 29 additions & 0 deletions dot/sync/mock_runtime_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions dot/types/equivocation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2023 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package types

import "github.com/ChainSafe/gossamer/lib/crypto/sr25519"

// BabeEquivocationProof represents a babe equivocation proof.
// An equivocation happens when a validator produces more than one block on the same slot.
// The proof of equivocation are the given distinct headers that were signed by the validator
// and which include the slot number.
type BabeEquivocationProof struct {
// Offender is the public key of the equivocator.
Offender AuthorityID
// Slot at which the equivocation happened.
Slot uint64
// FirstHeader is the first header involved in the equivocation.
FirstHeader Header
// SecondHeader is the second header involved in the equivocation.
SecondHeader Header
}

// AuthorityID represents a babe authority identifier.
type AuthorityID [sr25519.PublicKeyLength]byte

// OpaqueKeyOwnershipProof is an opaque type used to represent the key ownership proof at the
// runtime API boundary. The inner value is an encoded representation of the actual key
// ownership proof which will be parameterized when defining the runtime. At
// the runtime API boundary this type is unknown and as such we keep this
// opaque representation, implementers of the runtime API will have to make
// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type.
type OpaqueKeyOwnershipProof []byte
30 changes: 30 additions & 0 deletions dot/types/equivocation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2022 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package types

import (
"testing"

"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"
"github.com/stretchr/testify/require"
)

func TestEquivocationProof(t *testing.T) {
// To get these bytes run
// https://github.com/paritytech/substrate/blob/17c07af0b953b84dbe89341294e98e586f9b4591/frame/babe/src/tests.rs#L932
expectedEncoding := common.MustHexToBytes("0xdef12e42f3e487e9b14095aa8d5cc16a33491f1b50dadcf8811d1480f3fa86270b0000000000000043fd935464ab466417a2d3b51b750b3047acc94708aa8e69bb01d19e7ba841f428cee631e4d752a4de8130431b63246d695dcc87af881316251bc6d35651f9508a03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c1113140c06424142453402000000000a0000000000000004424142456902010cdef12e42f3e487e9b14095aa8d5cc16a33491f1b50dadcf8811d1480f3fa862701000000000000003a3d45dc55b57bf542f4c6ff41af080ec675317f4ed50ae1d2713bf9f892692d010000000000000054c71c235773b82115f0744252369c13414fd0e8bad3e8feff462c6a4bb58a0f0100000000000000c6e9d02ce38de7b255382f804a64f9bc74aad5597f51fde6bb53c0b8a76c22ba054241424501015881750a61f36303470033d7a9c4d5654ee4d11983ba73008cbe4af8e0361e62b1e67b58236a4258f17ceed53d11e204528238a412eab6ce3476e9d3eb42c18143fd935464ab466417a2d3b51b750b3047acc94708aa8e69bb01d19e7ba841f428cee631e4d752a4de8130431b63246d695dcc87af881316251bc6d35651f9508a03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c1113140c06424142453402000000000a0000000000000004424142456902010cdef12e42f3e487e9b14095aa8d5cc16a33491f1b50dadcf8811d1480f3fa862701000000000000003a3d45dc55b57bf542f4c6ff41af080ec675317f4ed50ae1d2713bf9f892692d010000000000000054c71c235773b82115f0744252369c13414fd0e8bad3e8feff462c6a4bb58a0f0100000000000000c6e9d02ce38de7b255382f804a64f9bc74aad5597f51fde6bb53c0b8a76c22ba05424142450101e4df6a034d5057b1eace2dd4918f2357c5ab0413615596ebee5129fb0fcf146a087c8b3b65d55f76ebf91a77504e334be9b6a36cb836adf58cfd1756b149b689") //nolint:lll

decodedProof := BabeEquivocationProof{
FirstHeader: *NewEmptyHeader(),
SecondHeader: *NewEmptyHeader(),
}

err := scale.Unmarshal(expectedEncoding, &decodedProof)
require.NoError(t, err)

actualEncoding, err := scale.Marshal(decodedProof)
require.NoError(t, err)
require.Equal(t, expectedEncoding, actualEncoding)
}
3 changes: 3 additions & 0 deletions lib/babe/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
)

var (
// ErrAuthIndexOutOfBound is returned when a authority index doesn't exist
ErrAuthIndexOutOfBound = errors.New("authority index doesn't exist")

// ErrBadSlotClaim is returned when a slot claim is invalid
ErrBadSlotClaim = errors.New("could not verify slot claim VRF proof")

Expand Down
Loading

0 comments on commit 55de62e

Please sign in to comment.