Skip to content

Commit

Permalink
feat(dot/parachain/backing): implement statement table method to drai…
Browse files Browse the repository at this point in the history
…n missbehaviours (#3996)

- This PR implements a method to drain misbehaviour.
- I changed the returned type of interface method to drain misbehaviours.
- Written the unit test
  • Loading branch information
axaysagathiya committed Jun 13, 2024
1 parent 08e0381 commit c35cb4e
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 38 deletions.
35 changes: 16 additions & 19 deletions dot/parachain/backing/candidate_backing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ func rpStateWhenPpmDisabled(t *testing.T) perRelayParentState {
mockTable := NewMockTable(ctrl)

mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -475,11 +475,8 @@ func TestPostImportStatement(t *testing.T) {
ctrl := gomock.NewController(t)
mockTable := NewMockTable(ctrl)

mockTable.EXPECT().drainMisbehaviors().Return([]parachaintypes.ProvisionableDataMisbehaviorReport{
{
ValidatorIndex: 1,
Misbehaviour: parachaintypes.MultipleCandidates{},
},
mockTable.EXPECT().drainMisbehaviors().Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{
1: {parachaintypes.MultipleCandidates{}},
})

return perRelayParentState{
Expand All @@ -495,7 +492,7 @@ func TestPostImportStatement(t *testing.T) {
mockTable := NewMockTable(ctrl)

mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand All @@ -521,7 +518,7 @@ func TestPostImportStatement(t *testing.T) {
candidateHash := parachaintypes.CandidateHash{Value: hash}

mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand All @@ -547,7 +544,7 @@ func TestPostImportStatement(t *testing.T) {
mockTable := NewMockTable(ctrl)

mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -913,7 +910,7 @@ func TestHandleStatementMessage(t *testing.T) {
gomock.AssignableToTypeOf(parachaintypes.SignedFullStatement{}),
).Return(nil, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})

return map[common.Hash]*perRelayParentState{
relayParent: {
Expand Down Expand Up @@ -942,7 +939,7 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -978,7 +975,7 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -1016,7 +1013,7 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -1057,7 +1054,7 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -1101,7 +1098,7 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
Expand Down Expand Up @@ -1152,13 +1149,13 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
gomock.AssignableToTypeOf(uint32(0)),
).Return(new(attestedCandidate), nil)
mockTable.EXPECT().getCandidate(
mockTable.EXPECT().getCommittedCandidateReceipt(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
).Return(
parachaintypes.CommittedCandidateReceipt{},
Expand Down Expand Up @@ -1196,13 +1193,13 @@ func TestHandleStatementMessage(t *testing.T) {
GroupID: 4,
}, nil)
mockTable.EXPECT().drainMisbehaviors().
Return([]parachaintypes.ProvisionableDataMisbehaviorReport{})
Return(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{})
mockTable.EXPECT().attestedCandidate(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
gomock.AssignableToTypeOf(new(tableContext)),
gomock.AssignableToTypeOf(uint32(0)),
).Return(new(attestedCandidate), nil)
mockTable.EXPECT().getCandidate(
mockTable.EXPECT().getCommittedCandidateReceipt(
gomock.AssignableToTypeOf(parachaintypes.CandidateHash{}),
).Return(dummyCCR, nil)

Expand Down
12 changes: 6 additions & 6 deletions dot/parachain/backing/mocks_test.go

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

21 changes: 12 additions & 9 deletions dot/parachain/backing/per_relay_parent_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,24 +189,27 @@ func (rpState *perRelayParentState) postImportStatement(subSystemToOverseer chan

// issueNewMisbehaviors checks for new misbehaviors and sends necessary messages to the Overseer subsystem.
func issueNewMisbehaviors(subSystemToOverseer chan<- any, relayParent common.Hash, table Table) {
// collect the misbehaviors to avoid double mutable self borrow issues
misbehaviors := table.drainMisbehaviors()
// collect the validatorsToMisbehaviors to avoid double mutable self borrow issues
validatorsToMisbehaviors := table.drainMisbehaviors()

for _, m := range misbehaviors {
for validatorIndex, misbehaviours := range validatorsToMisbehaviors {
// TODO: figure out what this comment means by 'avoid cycles'.
//
// The provisioner waits on candidate-backing, which means
// that we need to send unbounded messages to avoid cycles.
//
// Misbehaviors are bounded by the number of validators and
// the block production protocol.
subSystemToOverseer <- parachaintypes.ProvisionerMessageProvisionableData{
RelayParent: relayParent,
ProvisionableData: parachaintypes.ProvisionableDataMisbehaviorReport{
ValidatorIndex: m.ValidatorIndex,
Misbehaviour: m.Misbehaviour,
},
for _, misbehaviour := range misbehaviours {
subSystemToOverseer <- parachaintypes.ProvisionerMessageProvisionableData{
RelayParent: relayParent,
ProvisionableData: parachaintypes.ProvisionableDataMisbehaviorReport{
ValidatorIndex: validatorIndex,
Misbehaviour: misbehaviour,
},
}
}

}
}

Expand Down
10 changes: 6 additions & 4 deletions dot/parachain/backing/statement_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,18 @@ func effectiveMinimumBackingVotes(groupLen uint, configuredMinimumBackingVotes u
return min(groupLen, uint(configuredMinimumBackingVotes))
}

func (statementTable) drainMisbehaviors() []parachaintypes.ProvisionableDataMisbehaviorReport {
// TODO: Implement this method
return nil
// drainMisbehaviors returns the current detected misbehaviors and resets the internal map.
func (table *statementTable) drainMisbehaviors() map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour {
mapToReturn := table.detectedMisbehaviour
table.detectedMisbehaviour = make(map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour)
return mapToReturn
}

type Table interface {
getCommittedCandidateReceipt(parachaintypes.CandidateHash) (parachaintypes.CommittedCandidateReceipt, error)
importStatement(*tableContext, parachaintypes.SignedFullStatement) (*Summary, error)
attestedCandidate(parachaintypes.CandidateHash, *tableContext, uint32) (*attestedCandidate, error)
drainMisbehaviors() []parachaintypes.ProvisionableDataMisbehaviorReport
drainMisbehaviors() map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour
}

func newTable(config tableConfig) *statementTable {
Expand Down
44 changes: 44 additions & 0 deletions dot/parachain/backing/statement_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,3 +604,47 @@ func TestStatementTable_validityVote(t *testing.T) {
})
}
}

func TestStatementTable_drainMisbehaviors(t *testing.T) {
t.Parallel()

committedCandidate := getDummyCommittedCandidateReceipt(t)

candidateHash, err := parachaintypes.GetCandidateHash(committedCandidate)
require.NoError(t, err)

var validatorSign parachaintypes.ValidatorSignature
var tempSignature = common.MustHexToBytes("0xc67cb93bf0a36fcee3d29de8a6a69a759659680acf486475e0a2552a5fbed87e45adce5f290698d8596095722b33599227f7461f51af8617c8be74b894cf1b86") //nolint:lll
copy(validatorSign[:], tempSignature)

oldSign := parachaintypes.ValidatorSignature{}

valToMic := map[parachaintypes.ValidatorIndex][]parachaintypes.Misbehaviour{
1: {
parachaintypes.ValidityDoubleVoteIssuedAndValidity{
CommittedCandidateReceiptAndSign: parachaintypes.CommittedCandidateReceiptAndSign{
CommittedCandidateReceipt: committedCandidate,
Signature: oldSign,
},
CandidateHashAndSign: parachaintypes.CandidateHashAndSign{
CandidateHash: candidateHash,
Signature: validatorSign,
},
},

parachaintypes.DoubleSignOnValidity{
CandidateHash: candidateHash,
Sign1: oldSign,
Sign2: validatorSign,
},
},
}

table := &statementTable{
detectedMisbehaviour: valToMic,
}

misbehaviours := table.drainMisbehaviors()
require.Equal(t, valToMic, misbehaviours)
require.Empty(t, table.detectedMisbehaviour)
}

0 comments on commit c35cb4e

Please sign in to comment.