diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 39c7de9e2..8faf2c080 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -253,7 +253,13 @@ func (s *service) getTx(h util.Uint256) block.Transaction { tx, _, _ := s.Config.Chain.GetTransaction(h) - return tx + // this is needed because in case of absent tx dBFT expects to + // get nil interface, not a nil pointer to any concrete type + if tx != nil { + return tx + } + + return nil } func (s *service) verifyBlock(b block.Block) bool { diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index d934906fc..3d86e969a 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -56,6 +56,37 @@ func TestService_ValidatePayload(t *testing.T) { }) } +func TestService_getTx(t *testing.T) { + srv := newTestService(t) + + t.Run("transaction in mempool", func(t *testing.T) { + tx := newMinerTx(1234) + h := tx.Hash() + + require.Equal(t, nil, srv.getTx(h)) + + item := core.NewPoolItem(tx, new(feer)) + srv.Chain.GetMemPool().TryAdd(h, item) + + got := srv.getTx(h) + require.NotNil(t, got) + require.Equal(t, h, got.Hash()) + }) + + t.Run("transaction in local cache", func(t *testing.T) { + tx := newMinerTx(4321) + h := tx.Hash() + + require.Equal(t, nil, srv.getTx(h)) + + srv.txx.Add(tx) + + got := srv.getTx(h) + require.NotNil(t, got) + require.Equal(t, h, got.Hash()) + }) +} + func TestService_OnPayload(t *testing.T) { srv := newTestService(t)