Skip to content

Commit 5091028

Browse files
committed
Remove dependency on activation/wire from sql/identities (#6330)
## Motivation The `sql/identities` package depends on `activation/wire`. `sql` packages should not import `wire` packages, rather should be oblivious to specific encodings of wire types. This PR removes this dependency.
1 parent a28991f commit 5091028

File tree

12 files changed

+242
-236
lines changed

12 files changed

+242
-236
lines changed

activation/handler_test.go

Lines changed: 132 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -224,79 +224,94 @@ func newTestHandler(tb testing.TB, goldenATXID types.ATXID, opts ...HandlerOptio
224224
}
225225
}
226226

227-
func testHandler_PostMalfeasanceProofs(t *testing.T, synced bool) {
228-
goldenATXID := types.ATXID{2, 3, 4}
229-
atxHdlr := newTestHandler(t, goldenATXID)
230-
231-
sig, err := signing.NewEdSigner()
232-
require.NoError(t, err)
227+
func TestHandler_PostMalfeasanceProofs(t *testing.T) {
228+
t.Run("produced but not published during sync", func(t *testing.T) {
229+
t.Parallel()
230+
goldenATXID := types.ATXID{2, 3, 4}
231+
atxHdlr := newTestHandler(t, goldenATXID)
232+
sig, err := signing.NewEdSigner()
233+
require.NoError(t, err)
233234

234-
_, err = identities.GetMalfeasanceProof(atxHdlr.cdb, sig.NodeID())
235-
require.ErrorIs(t, err, sql.ErrNotFound)
235+
malicious, err := identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
236+
require.NoError(t, err)
237+
require.False(t, malicious)
236238

237-
atx := newInitialATXv1(t, goldenATXID)
238-
atx.Sign(sig)
239+
atx := newInitialATXv1(t, goldenATXID)
240+
atx.Sign(sig)
239241

240-
var got mwire.MalfeasanceGossip
241-
atxHdlr.mclock.EXPECT().CurrentLayer().Return(atx.PublishEpoch.FirstLayer())
242-
atxHdlr.mValidator.EXPECT().VRFNonce(atx.SmesherID, goldenATXID, *atx.VRFNonce, gomock.Any(), atx.NumUnits)
243-
atxHdlr.mValidator.EXPECT().
244-
Post(gomock.Any(), gomock.Any(), *atx.CommitmentATXID, gomock.Any(), gomock.Any(), atx.NumUnits)
245-
atxHdlr.mockFetch.EXPECT().RegisterPeerHashes(gomock.Any(), gomock.Any())
246-
atxHdlr.mockFetch.EXPECT().GetPoetProof(gomock.Any(), gomock.Any())
247-
atxHdlr.mValidator.EXPECT().InitialNIPostChallengeV1(gomock.Any(), gomock.Any(), goldenATXID)
248-
atxHdlr.mValidator.EXPECT().PositioningAtx(atx.PositioningATXID, gomock.Any(), goldenATXID, atx.PublishEpoch)
249-
atxHdlr.mValidator.EXPECT().
250-
NIPost(gomock.Any(), atx.SmesherID, goldenATXID, gomock.Any(), gomock.Any(), atx.NumUnits, gomock.Any()).
251-
Return(0, &verifying.ErrInvalidIndex{Index: 2})
252-
atxHdlr.mtortoise.EXPECT().OnMalfeasance(gomock.Any())
253-
254-
msg := codec.MustEncode(atx)
255-
if synced {
242+
atxHdlr.mclock.EXPECT().CurrentLayer().Return(atx.PublishEpoch.FirstLayer())
243+
atxHdlr.mValidator.EXPECT().VRFNonce(atx.SmesherID, goldenATXID, *atx.VRFNonce, gomock.Any(), atx.NumUnits)
244+
atxHdlr.mValidator.EXPECT().
245+
Post(gomock.Any(), gomock.Any(), *atx.CommitmentATXID, gomock.Any(), gomock.Any(), atx.NumUnits)
246+
atxHdlr.mockFetch.EXPECT().RegisterPeerHashes(gomock.Any(), gomock.Any())
247+
atxHdlr.mockFetch.EXPECT().GetPoetProof(gomock.Any(), gomock.Any())
248+
atxHdlr.mValidator.EXPECT().InitialNIPostChallengeV1(gomock.Any(), gomock.Any(), goldenATXID)
249+
atxHdlr.mValidator.EXPECT().PositioningAtx(atx.PositioningATXID, gomock.Any(), goldenATXID, atx.PublishEpoch)
250+
atxHdlr.mValidator.EXPECT().
251+
NIPost(gomock.Any(), atx.SmesherID, goldenATXID, gomock.Any(), gomock.Any(), atx.NumUnits, gomock.Any()).
252+
Return(0, &verifying.ErrInvalidIndex{Index: 2})
253+
atxHdlr.mtortoise.EXPECT().OnMalfeasance(gomock.Any())
254+
255+
msg := codec.MustEncode(atx)
256256
require.NoError(t, atxHdlr.HandleSyncedAtx(context.Background(), types.Hash32{}, p2p.NoPeer, msg))
257-
} else {
257+
258+
// identity is still marked as malicious
259+
malicious, err = identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
260+
require.NoError(t, err)
261+
require.True(t, malicious)
262+
})
263+
264+
t.Run("produced and published during gossip", func(t *testing.T) {
265+
t.Parallel()
266+
goldenATXID := types.ATXID{2, 3, 4}
267+
atxHdlr := newTestHandler(t, goldenATXID)
268+
sig, err := signing.NewEdSigner()
269+
require.NoError(t, err)
270+
271+
malicious, err := identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
272+
require.NoError(t, err)
273+
require.False(t, malicious)
274+
275+
atx := newInitialATXv1(t, goldenATXID)
276+
atx.Sign(sig)
277+
278+
atxHdlr.mclock.EXPECT().CurrentLayer().Return(atx.PublishEpoch.FirstLayer())
279+
atxHdlr.mValidator.EXPECT().VRFNonce(atx.SmesherID, goldenATXID, *atx.VRFNonce, gomock.Any(), atx.NumUnits)
280+
atxHdlr.mValidator.EXPECT().
281+
Post(gomock.Any(), gomock.Any(), *atx.CommitmentATXID, gomock.Any(), gomock.Any(), atx.NumUnits)
282+
atxHdlr.mockFetch.EXPECT().RegisterPeerHashes(gomock.Any(), gomock.Any())
283+
atxHdlr.mockFetch.EXPECT().GetPoetProof(gomock.Any(), gomock.Any())
284+
atxHdlr.mValidator.EXPECT().InitialNIPostChallengeV1(gomock.Any(), gomock.Any(), goldenATXID)
285+
atxHdlr.mValidator.EXPECT().PositioningAtx(atx.PositioningATXID, gomock.Any(), goldenATXID, atx.PublishEpoch)
286+
atxHdlr.mValidator.EXPECT().
287+
NIPost(gomock.Any(), atx.SmesherID, goldenATXID, gomock.Any(), gomock.Any(), atx.NumUnits, gomock.Any()).
288+
Return(0, &verifying.ErrInvalidIndex{Index: 2})
289+
atxHdlr.mtortoise.EXPECT().OnMalfeasance(gomock.Any())
290+
msg := codec.MustEncode(atx)
291+
258292
postVerifier := NewMockPostVerifier(gomock.NewController(t))
259-
mh := NewInvalidPostIndexHandler(atxHdlr.cdb,
260-
atxHdlr.logger,
261-
atxHdlr.edVerifier,
262-
postVerifier,
263-
)
264-
atxHdlr.mpub.EXPECT().Publish(gomock.Any(), pubsub.MalfeasanceProof, gomock.Any()).DoAndReturn(
265-
func(_ context.Context, _ string, data []byte) error {
293+
mh := NewInvalidPostIndexHandler(atxHdlr.cdb, atxHdlr.logger, atxHdlr.edVerifier, postVerifier)
294+
atxHdlr.mpub.EXPECT().Publish(gomock.Any(), pubsub.MalfeasanceProof, gomock.Any()).
295+
DoAndReturn(func(_ context.Context, _ string, data []byte) error {
296+
var got mwire.MalfeasanceGossip
266297
require.NoError(t, codec.Decode(data, &got))
267298
require.Equal(t, mwire.InvalidPostIndex, got.Proof.Type)
268-
269-
postVerifier.EXPECT().Verify(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
299+
postVerifier.EXPECT().
300+
Verify(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
270301
Return(errors.New("invalid"))
271302
nodeID, err := mh.Validate(context.Background(), got.Proof.Data)
272303
require.NoError(t, err)
273304
require.Equal(t, sig.NodeID(), nodeID)
274-
275305
p, ok := got.Proof.Data.(*mwire.InvalidPostIndexProof)
276306
require.True(t, ok)
277307
require.EqualValues(t, 2, p.InvalidIdx)
278308
return nil
279309
})
280310
require.ErrorIs(t, atxHdlr.HandleGossipAtx(context.Background(), p2p.NoPeer, msg), errMaliciousATX)
281-
}
282-
283-
proof, err := identities.GetMalfeasanceProof(atxHdlr.cdb, atx.SmesherID)
284-
require.NoError(t, err)
285-
require.NotNil(t, proof.Received())
286-
proof.SetReceived(time.Time{})
287-
if !synced {
288-
require.Equal(t, got.MalfeasanceProof, *proof)
289-
require.Equal(t, atx.PublishEpoch.FirstLayer(), got.MalfeasanceProof.Layer)
290-
}
291-
}
292-
293-
func TestHandler_PostMalfeasanceProofs(t *testing.T) {
294-
t.Run("produced but not published during sync", func(t *testing.T) {
295-
testHandler_PostMalfeasanceProofs(t, true)
296-
})
297311

298-
t.Run("produced and published during gossip", func(t *testing.T) {
299-
testHandler_PostMalfeasanceProofs(t, false)
312+
malicious, err = identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
313+
require.NoError(t, err)
314+
require.True(t, malicious)
300315
})
301316
}
302317

@@ -400,57 +415,79 @@ func TestHandler_HandleParallelGossipAtxV1(t *testing.T) {
400415
require.NoError(t, eg.Wait())
401416
}
402417

403-
func testHandler_HandleDoublePublish(t *testing.T, synced bool) {
404-
t.Parallel()
405-
goldenATXID := types.ATXID{2, 3, 4}
406-
sig, err := signing.NewEdSigner()
407-
require.NoError(t, err)
408-
hdlr := newTestHandler(t, goldenATXID)
418+
func TestHandler_HandleMaliciousAtx(t *testing.T) {
419+
t.Run("produced but not published during sync", func(t *testing.T) {
420+
t.Parallel()
421+
goldenATXID := types.ATXID{2, 3, 4}
422+
sig, err := signing.NewEdSigner()
423+
require.NoError(t, err)
409424

410-
atx1 := newInitialATXv1(t, goldenATXID)
411-
atx1.Sign(sig)
412-
hdlr.expectAtxV1(atx1, sig.NodeID())
413-
require.NoError(t, hdlr.HandleGossipAtx(context.Background(), "", codec.MustEncode(atx1)))
425+
atxHdlr := newTestHandler(t, goldenATXID)
426+
atx1 := newInitialATXv1(t, goldenATXID)
427+
atx1.Sign(sig)
428+
atxHdlr.expectAtxV1(atx1, sig.NodeID())
429+
require.NoError(t, atxHdlr.HandleGossipAtx(context.Background(), "", codec.MustEncode(atx1)))
414430

415-
atx2 := newInitialATXv1(t, goldenATXID, func(a *wire.ActivationTxV1) { a.NumUnits = atx1.NumUnits + 1 })
416-
atx2.Sign(sig)
417-
hdlr.expectAtxV1(atx2, sig.NodeID())
418-
hdlr.mtortoise.EXPECT().OnMalfeasance(sig.NodeID())
431+
malicious, err := identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
432+
require.NoError(t, err)
433+
require.False(t, malicious)
419434

420-
msg := codec.MustEncode(atx2)
421-
var got mwire.MalfeasanceGossip
422-
if synced {
423-
require.NoError(t, hdlr.HandleSyncedAtx(context.Background(), types.Hash32{}, "", msg))
424-
} else {
425-
mh := NewMalfeasanceHandler(hdlr.cdb, hdlr.logger, hdlr.edVerifier)
426-
hdlr.mpub.EXPECT().Publish(gomock.Any(), pubsub.MalfeasanceProof, gomock.Any()).DoAndReturn(
427-
func(_ context.Context, _ string, data []byte) error {
435+
atx2 := newInitialATXv1(t, goldenATXID, func(a *wire.ActivationTxV1) {
436+
a.NumUnits = atx1.NumUnits + 1
437+
})
438+
atx2.Sign(sig)
439+
atxHdlr.expectAtxV1(atx2, sig.NodeID())
440+
441+
atxHdlr.mtortoise.EXPECT().OnMalfeasance(sig.NodeID())
442+
msg := codec.MustEncode(atx2)
443+
require.NoError(t, atxHdlr.HandleSyncedAtx(context.Background(), types.Hash32{}, "", msg))
444+
445+
// identity is still marked as malicious
446+
malicious, err = identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
447+
require.NoError(t, err)
448+
require.True(t, malicious)
449+
})
450+
451+
t.Run("produced and published during gossip", func(t *testing.T) {
452+
t.Parallel()
453+
goldenATXID := types.ATXID{2, 3, 4}
454+
sig, err := signing.NewEdSigner()
455+
require.NoError(t, err)
456+
457+
atxHdlr := newTestHandler(t, goldenATXID)
458+
atx1 := newInitialATXv1(t, goldenATXID)
459+
atx1.Sign(sig)
460+
atxHdlr.expectAtxV1(atx1, sig.NodeID())
461+
require.NoError(t, atxHdlr.HandleGossipAtx(context.Background(), "", codec.MustEncode(atx1)))
462+
463+
malicious, err := identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
464+
require.NoError(t, err)
465+
require.False(t, malicious)
466+
467+
atx2 := newInitialATXv1(t, goldenATXID, func(a *wire.ActivationTxV1) {
468+
a.NumUnits = atx1.NumUnits + 1
469+
})
470+
atx2.Sign(sig)
471+
atxHdlr.expectAtxV1(atx2, sig.NodeID())
472+
atxHdlr.mtortoise.EXPECT().OnMalfeasance(sig.NodeID())
473+
msg := codec.MustEncode(atx2)
474+
475+
mh := NewMalfeasanceHandler(atxHdlr.cdb, atxHdlr.logger, atxHdlr.edVerifier)
476+
atxHdlr.mpub.EXPECT().Publish(gomock.Any(), pubsub.MalfeasanceProof, gomock.Any()).
477+
DoAndReturn(func(_ context.Context, _ string, data []byte) error {
478+
var got mwire.MalfeasanceGossip
428479
require.NoError(t, codec.Decode(data, &got))
429480
require.Equal(t, mwire.MultipleATXs, got.Proof.Type)
430481
nodeID, err := mh.Validate(context.Background(), got.Proof.Data)
431482
require.NoError(t, err)
432483
require.Equal(t, sig.NodeID(), nodeID)
433484
return nil
434485
})
435-
require.ErrorIs(t, hdlr.HandleGossipAtx(context.Background(), p2p.NoPeer, msg), errMaliciousATX)
436-
}
437-
438-
proof, err := identities.GetMalfeasanceProof(hdlr.cdb, sig.NodeID())
439-
require.NoError(t, err)
440-
require.NotNil(t, proof)
441-
if !synced {
442-
proof.SetReceived(time.Time{})
443-
require.Equal(t, got.MalfeasanceProof, *proof)
444-
}
445-
}
446-
447-
func TestHandler_HandleMaliciousAtx(t *testing.T) {
448-
t.Run("produced but not published during sync", func(t *testing.T) {
449-
testHandler_HandleDoublePublish(t, true)
450-
})
486+
require.ErrorIs(t, atxHdlr.HandleGossipAtx(context.Background(), p2p.NoPeer, msg), errMaliciousATX)
451487

452-
t.Run("produced and published during gossip", func(t *testing.T) {
453-
testHandler_HandleDoublePublish(t, false)
488+
malicious, err = identities.IsMalicious(atxHdlr.cdb, sig.NodeID())
489+
require.NoError(t, err)
490+
require.True(t, malicious)
454491
})
455492
}
456493

api/grpcserver/activation_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func (s *activationService) Get(ctx context.Context, request *pb.GetRequest) (*p
7272
return nil, status.Error(codes.Internal, "couldn't get previous ATXs")
7373
}
7474

75-
proof, err := s.atxProvider.GetMalfeasanceProof(atx.SmesherID)
75+
proof, err := s.atxProvider.MalfeasanceProof(atx.SmesherID)
7676
if err != nil && !errors.Is(err, sql.ErrNotFound) {
7777
ctxzap.Error(ctx, "failed to get malfeasance proof",
7878
zap.Stringer("smesher", atx.SmesherID),

api/grpcserver/activation_service_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func TestGet_HappyPath(t *testing.T) {
133133
}
134134
atx.SetID(id)
135135
atxProvider.EXPECT().GetAtx(id).Return(&atx, nil)
136-
atxProvider.EXPECT().GetMalfeasanceProof(gomock.Any()).Return(nil, sql.ErrNotFound)
136+
atxProvider.EXPECT().MalfeasanceProof(gomock.Any()).Return(nil, sql.ErrNotFound)
137137
atxProvider.EXPECT().Previous(id).Return(previous, nil)
138138

139139
response, err := activationService.Get(context.Background(), &pb.GetRequest{Id: id.Bytes()})
@@ -169,7 +169,7 @@ func TestGet_IdentityCanceled(t *testing.T) {
169169
}
170170
atx.SetID(id)
171171
atxProvider.EXPECT().GetAtx(id).Return(&atx, nil)
172-
atxProvider.EXPECT().GetMalfeasanceProof(smesher).Return(proof, nil)
172+
atxProvider.EXPECT().MalfeasanceProof(smesher).Return(proof, nil)
173173
atxProvider.EXPECT().Previous(id).Return([]types.ATXID{previous}, nil)
174174

175175
response, err := activationService.Get(context.Background(), &pb.GetRequest{Id: id.Bytes()})

api/grpcserver/interface.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ type atxProvider interface {
5858
GetAtx(id types.ATXID) (*types.ActivationTx, error)
5959
Previous(id types.ATXID) ([]types.ATXID, error)
6060
MaxHeightAtx() (types.ATXID, error)
61-
GetMalfeasanceProof(id types.NodeID) (*wire.MalfeasanceProof, error)
61+
MalfeasanceProof(id types.NodeID) (*wire.MalfeasanceProof, error)
6262
}
6363

6464
type postState interface {

api/grpcserver/mesh_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ func (s *MeshService) MalfeasanceQuery(
611611
fmt.Sprintf("invalid smesher id length (%d), expected (%d)", l, types.NodeIDSize))
612612
}
613613
id := types.BytesToNodeID(parsed)
614-
proof, err := s.cdb.GetMalfeasanceProof(id)
614+
proof, err := s.cdb.MalfeasanceProof(id)
615615
if err != nil && !errors.Is(err, sql.ErrNotFound) {
616616
return nil, status.Error(codes.Internal, err.Error())
617617
}

api/grpcserver/mocks.go

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)