github.com/braveheart12/just@v0.8.7/ledger/artifactmanager/handler_test.go (about)

     1  /*
     2   *    Copyright 2019 Insolar Technologies
     3   *
     4   *    Licensed under the Apache License, Version 2.0 (the "License");
     5   *    you may not use this file except in compliance with the License.
     6   *    You may obtain a copy of the License at
     7   *
     8   *        http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   *    Unless required by applicable law or agreed to in writing, software
    11   *    distributed under the License is distributed on an "AS IS" BASIS,
    12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *    See the License for the specific language governing permissions and
    14   *    limitations under the License.
    15   */
    16  
    17  package artifactmanager
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"testing"
    23  
    24  	"github.com/gojuno/minimock"
    25  	"github.com/insolar/insolar/component"
    26  	"github.com/insolar/insolar/configuration"
    27  	"github.com/insolar/insolar/core"
    28  	"github.com/insolar/insolar/core/delegationtoken"
    29  	"github.com/insolar/insolar/core/message"
    30  	"github.com/insolar/insolar/core/reply"
    31  	"github.com/insolar/insolar/instrumentation/inslogger"
    32  	"github.com/insolar/insolar/ledger/recentstorage"
    33  	"github.com/insolar/insolar/ledger/storage"
    34  	"github.com/insolar/insolar/ledger/storage/index"
    35  	"github.com/insolar/insolar/ledger/storage/jet"
    36  	"github.com/insolar/insolar/ledger/storage/nodes"
    37  	"github.com/insolar/insolar/ledger/storage/record"
    38  	"github.com/insolar/insolar/ledger/storage/storagetest"
    39  	"github.com/insolar/insolar/platformpolicy"
    40  	"github.com/insolar/insolar/testutils"
    41  	"github.com/insolar/insolar/testutils/network"
    42  	"github.com/stretchr/testify/assert"
    43  	"github.com/stretchr/testify/require"
    44  	"github.com/stretchr/testify/suite"
    45  )
    46  
    47  type handlerSuite struct {
    48  	suite.Suite
    49  
    50  	cm      *component.Manager
    51  	ctx     context.Context
    52  	cleaner func()
    53  	db      storage.DBContext
    54  
    55  	scheme        core.PlatformCryptographyScheme
    56  	pulseTracker  storage.PulseTracker
    57  	nodeStorage   nodes.Accessor
    58  	objectStorage storage.ObjectStorage
    59  	jetStorage    storage.JetStorage
    60  	dropStorage   storage.DropStorage
    61  }
    62  
    63  func NewHandlerSuite() *handlerSuite {
    64  	return &handlerSuite{
    65  		Suite: suite.Suite{},
    66  	}
    67  }
    68  
    69  // Init and run suite
    70  func TestHandlerSuite(t *testing.T) {
    71  	suite.Run(t, NewHandlerSuite())
    72  }
    73  
    74  func (s *handlerSuite) BeforeTest(suiteName, testName string) {
    75  	s.cm = &component.Manager{}
    76  	s.ctx = inslogger.TestContext(s.T())
    77  
    78  	db, cleaner := storagetest.TmpDB(s.ctx, s.T())
    79  	s.cleaner = cleaner
    80  	s.db = db
    81  	s.scheme = testutils.NewPlatformCryptographyScheme()
    82  	s.jetStorage = storage.NewJetStorage()
    83  	s.nodeStorage = nodes.NewStorage()
    84  	s.pulseTracker = storage.NewPulseTracker()
    85  	s.objectStorage = storage.NewObjectStorage()
    86  	s.dropStorage = storage.NewDropStorage(10)
    87  
    88  	s.cm.Inject(
    89  		s.scheme,
    90  		s.db,
    91  		s.jetStorage,
    92  		s.nodeStorage,
    93  		s.pulseTracker,
    94  		s.objectStorage,
    95  		s.dropStorage,
    96  	)
    97  
    98  	err := s.cm.Init(s.ctx)
    99  	if err != nil {
   100  		s.T().Error("ComponentManager init failed", err)
   101  	}
   102  	err = s.cm.Start(s.ctx)
   103  	if err != nil {
   104  		s.T().Error("ComponentManager start failed", err)
   105  	}
   106  }
   107  
   108  func (s *handlerSuite) AfterTest(suiteName, testName string) {
   109  	err := s.cm.Stop(s.ctx)
   110  	if err != nil {
   111  		s.T().Error("ComponentManager stop failed", err)
   112  	}
   113  	s.cleaner()
   114  }
   115  
   116  func (s *handlerSuite) TestMessageHandler_HandleGetObject_FetchesObject() {
   117  	mc := minimock.NewController(s.T())
   118  	defer mc.Finish()
   119  	jetID := *jet.NewID(0, nil)
   120  
   121  	tf := testutils.NewDelegationTokenFactoryMock(mc)
   122  	jc := testutils.NewJetCoordinatorMock(mc)
   123  	msg := message.GetObject{
   124  		Head: *genRandomRef(core.FirstPulseNumber),
   125  	}
   126  
   127  	certificate := testutils.NewCertificateMock(s.T())
   128  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   129  
   130  	h := NewMessageHandler(&configuration.Ledger{
   131  		LightChainLimit: 2,
   132  	}, certificate)
   133  	h.JetStorage = s.jetStorage
   134  	h.Nodes = s.nodeStorage
   135  	h.DBContext = s.db
   136  	h.PulseTracker = s.pulseTracker
   137  	h.ObjectStorage = s.objectStorage
   138  
   139  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   140  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   141  
   142  	indexMock.AddObjectMock.Return()
   143  	pendingMock.GetRequestsForObjectMock.Return(nil)
   144  	pendingMock.AddPendingRequestMock.Return()
   145  	pendingMock.RemovePendingRequestMock.Return()
   146  
   147  	provideMock := recentstorage.NewProviderMock(s.T())
   148  	provideMock.GetIndexStorageMock.Return(indexMock)
   149  	provideMock.GetPendingStorageMock.Return(pendingMock)
   150  
   151  	mb := testutils.NewMessageBusMock(mc)
   152  	mb.MustRegisterMock.Return()
   153  
   154  	h.RecentStorageProvider = provideMock
   155  	h.JetCoordinator = jc
   156  	h.DelegationTokenFactory = tf
   157  	h.Bus = mb
   158  
   159  	err := h.Init(s.ctx)
   160  	require.NoError(s.T(), err)
   161  
   162  	s.T().Run("fetches state from heavy when no index", func(t *testing.T) {
   163  		idxState := genRandomID(core.FirstPulseNumber)
   164  		objIndex := index.ObjectLifeline{
   165  			LatestState: idxState,
   166  		}
   167  		lightRef := genRandomRef(0)
   168  		heavyRef := genRandomRef(1)
   169  
   170  		mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   171  			if m, ok := gm.(*message.GetObjectIndex); ok {
   172  				assert.Equal(t, msg.Head, m.Object)
   173  				buf, err := index.EncodeObjectLifeline(&objIndex)
   174  				require.NoError(t, err)
   175  				return &reply.ObjectIndex{Index: buf}, nil
   176  			}
   177  
   178  			if _, ok := gm.(*message.GetObject); ok {
   179  				return &reply.Object{Memory: []byte{42, 16, 2}}, nil
   180  			}
   181  
   182  			panic("unexpected call")
   183  		}
   184  
   185  		jc.IsBeyondLimitMock.Return(false, nil)
   186  		jc.HeavyMock.Return(heavyRef, nil)
   187  		jc.NodeForJetMock.Return(lightRef, nil)
   188  
   189  		rep, err := h.handleGetObject(contextWithJet(s.ctx, jetID), &message.Parcel{
   190  			Msg:         &msg,
   191  			PulseNumber: core.FirstPulseNumber,
   192  		})
   193  		require.NoError(t, err)
   194  		obj, ok := rep.(*reply.Object)
   195  		require.True(t, ok)
   196  		assert.Equal(t, []byte{42, 16, 2}, obj.Memory)
   197  
   198  		idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Head.Record(), false)
   199  		require.NoError(t, err)
   200  		assert.Equal(t, objIndex.LatestState, idx.LatestState)
   201  	})
   202  
   203  	err = s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 1})
   204  	require.NoError(s.T(), err)
   205  	s.T().Run("fetches state from light when has index and state later than limit", func(t *testing.T) {
   206  		lightRef := genRandomRef(0)
   207  		jc.IsBeyondLimitMock.Return(false, nil)
   208  		jc.NodeForJetMock.Return(lightRef, nil)
   209  		stateID := genRandomID(core.FirstPulseNumber)
   210  		err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Head.Record(), &index.ObjectLifeline{
   211  			LatestState: stateID,
   212  		})
   213  		require.NoError(t, err)
   214  
   215  		mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   216  			if _, ok := gm.(*message.GetObject); ok {
   217  				return &reply.Object{Memory: []byte{42, 16, 2}}, nil
   218  			}
   219  
   220  			panic("unexpected call")
   221  		}
   222  
   223  		rep, err := h.handleGetObject(contextWithJet(s.ctx, jetID), &message.Parcel{
   224  			Msg:         &msg,
   225  			PulseNumber: core.FirstPulseNumber + 1,
   226  		})
   227  		require.NoError(t, err)
   228  		obj, ok := rep.(*reply.Object)
   229  		require.True(t, ok)
   230  		assert.Equal(t, []byte{42, 16, 2}, obj.Memory)
   231  	})
   232  
   233  	err = s.pulseTracker.AddPulse(s.ctx, core.Pulse{
   234  		PulseNumber: core.FirstPulseNumber + 2,
   235  	})
   236  	require.NoError(s.T(), err)
   237  	s.T().Run("fetches state from heavy when has index and state earlier than limit", func(t *testing.T) {
   238  		heavyRef := genRandomRef(0)
   239  		jc.IsBeyondLimitMock.Return(false, nil)
   240  		jc.NodeForJetMock.Return(heavyRef, nil)
   241  		stateID := genRandomID(core.FirstPulseNumber)
   242  
   243  		err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Head.Record(), &index.ObjectLifeline{
   244  			LatestState: stateID,
   245  		})
   246  		require.NoError(t, err)
   247  
   248  		mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   249  			if _, ok := gm.(*message.GetObject); ok {
   250  				return &reply.Object{Memory: []byte{42, 16, 2}}, nil
   251  			}
   252  
   253  			panic("unexpected call")
   254  		}
   255  
   256  		rep, err := h.handleGetObject(contextWithJet(s.ctx, jetID), &message.Parcel{
   257  			Msg:         &msg,
   258  			PulseNumber: core.FirstPulseNumber + 2,
   259  		})
   260  		require.NoError(t, err)
   261  		obj, ok := rep.(*reply.Object)
   262  		require.True(t, ok)
   263  		assert.Equal(t, []byte{42, 16, 2}, obj.Memory)
   264  	})
   265  }
   266  
   267  func (s *handlerSuite) TestMessageHandler_HandleGetChildren_Redirects() {
   268  	mc := minimock.NewController(s.T())
   269  	defer mc.Finish()
   270  	jetID := *jet.NewID(0, nil)
   271  
   272  	tf := testutils.NewDelegationTokenFactoryMock(mc)
   273  	tf.IssueGetChildrenRedirectMock.Return(&delegationtoken.GetChildrenRedirectToken{Signature: []byte{1, 2, 3}}, nil)
   274  	mb := testutils.NewMessageBusMock(mc)
   275  	mb.MustRegisterMock.Return()
   276  	jc := testutils.NewJetCoordinatorMock(mc)
   277  
   278  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   279  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   280  
   281  	indexMock.AddObjectMock.Return()
   282  	pendingMock.GetRequestsForObjectMock.Return(nil)
   283  	pendingMock.AddPendingRequestMock.Return()
   284  	pendingMock.RemovePendingRequestMock.Return()
   285  
   286  	provideMock := recentstorage.NewProviderMock(s.T())
   287  	provideMock.GetIndexStorageMock.Return(indexMock)
   288  	provideMock.GetPendingStorageMock.Return(pendingMock)
   289  
   290  	certificate := testutils.NewCertificateMock(s.T())
   291  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   292  
   293  	msg := message.GetChildren{
   294  		Parent: *genRandomRef(0),
   295  	}
   296  	h := NewMessageHandler(&configuration.Ledger{
   297  		LightChainLimit: 2,
   298  	}, certificate)
   299  	h.JetCoordinator = jc
   300  	h.DelegationTokenFactory = tf
   301  	h.Bus = mb
   302  	h.JetStorage = s.jetStorage
   303  	h.Nodes = s.nodeStorage
   304  	h.DBContext = s.db
   305  	h.PulseTracker = s.pulseTracker
   306  	h.ObjectStorage = s.objectStorage
   307  
   308  	err := h.Init(s.ctx)
   309  	require.NoError(s.T(), err)
   310  
   311  	h.RecentStorageProvider = provideMock
   312  
   313  	err = s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 1})
   314  	require.NoError(s.T(), err)
   315  
   316  	s.T().Run("redirects to heavy when no index", func(t *testing.T) {
   317  		objIndex := index.ObjectLifeline{
   318  			LatestState:  genRandomID(core.FirstPulseNumber),
   319  			ChildPointer: genRandomID(core.FirstPulseNumber),
   320  		}
   321  		mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   322  			if m, ok := gm.(*message.GetObjectIndex); ok {
   323  				assert.Equal(t, msg.Parent, m.Object)
   324  				buf, err := index.EncodeObjectLifeline(&objIndex)
   325  				require.NoError(t, err)
   326  				return &reply.ObjectIndex{Index: buf}, nil
   327  			}
   328  
   329  			panic("unexpected call")
   330  		}
   331  		heavyRef := genRandomRef(0)
   332  
   333  		jc.HeavyMock.Return(heavyRef, nil)
   334  		jc.IsBeyondLimitMock.Return(true, nil)
   335  		rep, err := h.handleGetChildren(contextWithJet(s.ctx, jetID), &message.Parcel{
   336  			Msg:         &msg,
   337  			PulseNumber: core.FirstPulseNumber + 1,
   338  		})
   339  		require.NoError(t, err)
   340  		redirect, ok := rep.(*reply.GetChildrenRedirectReply)
   341  		require.True(t, ok)
   342  		token, ok := redirect.Token.(*delegationtoken.GetChildrenRedirectToken)
   343  		assert.Equal(t, []byte{1, 2, 3}, token.Signature)
   344  		assert.Equal(t, heavyRef, redirect.GetReceiver())
   345  
   346  		idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Parent.Record(), false)
   347  		require.NoError(t, err)
   348  		assert.Equal(t, objIndex.LatestState, idx.LatestState)
   349  	})
   350  
   351  	s.T().Run("redirect to light when has index and child later than limit", func(t *testing.T) {
   352  		lightRef := genRandomRef(0)
   353  		jc.IsBeyondLimitMock.Return(false, nil)
   354  		jc.NodeForJetMock.Return(lightRef, nil)
   355  		err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Parent.Record(), &index.ObjectLifeline{
   356  			ChildPointer: genRandomID(core.FirstPulseNumber),
   357  		})
   358  		require.NoError(t, err)
   359  		rep, err := h.handleGetChildren(contextWithJet(s.ctx, jetID), &message.Parcel{
   360  			Msg:         &msg,
   361  			PulseNumber: core.FirstPulseNumber + 1,
   362  		})
   363  		require.NoError(t, err)
   364  		redirect, ok := rep.(*reply.GetChildrenRedirectReply)
   365  		require.True(t, ok)
   366  		token, ok := redirect.Token.(*delegationtoken.GetChildrenRedirectToken)
   367  		assert.Equal(t, []byte{1, 2, 3}, token.Signature)
   368  		assert.Equal(t, lightRef, redirect.GetReceiver())
   369  	})
   370  
   371  	s.T().Run("redirect to heavy when has index and child earlier than limit", func(t *testing.T) {
   372  		err = s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 2})
   373  		require.NoError(t, err)
   374  		heavyRef := genRandomRef(0)
   375  		jc.IsBeyondLimitMock.Return(false, nil)
   376  		jc.NodeForJetMock.Return(heavyRef, nil)
   377  		err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Parent.Record(), &index.ObjectLifeline{
   378  			ChildPointer: genRandomID(core.FirstPulseNumber),
   379  		})
   380  		require.NoError(t, err)
   381  		rep, err := h.handleGetChildren(contextWithJet(s.ctx, jetID), &message.Parcel{
   382  			Msg:         &msg,
   383  			PulseNumber: core.FirstPulseNumber + 2,
   384  		})
   385  		require.NoError(t, err)
   386  		redirect, ok := rep.(*reply.GetChildrenRedirectReply)
   387  		require.True(t, ok)
   388  		token, ok := redirect.Token.(*delegationtoken.GetChildrenRedirectToken)
   389  		assert.Equal(t, []byte{1, 2, 3}, token.Signature)
   390  		assert.Equal(t, heavyRef, redirect.GetReceiver())
   391  	})
   392  }
   393  
   394  func (s *handlerSuite) TestMessageHandler_HandleGetDelegate_FetchesIndexFromHeavy() {
   395  	mc := minimock.NewController(s.T())
   396  	defer mc.Finish()
   397  	jetID := *jet.NewID(0, nil)
   398  
   399  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   400  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   401  
   402  	indexMock.AddObjectMock.Return()
   403  	pendingMock.GetRequestsForObjectMock.Return(nil)
   404  	pendingMock.AddPendingRequestMock.Return()
   405  	pendingMock.RemovePendingRequestMock.Return()
   406  
   407  	provideMock := recentstorage.NewProviderMock(s.T())
   408  	provideMock.GetIndexStorageMock.Return(indexMock)
   409  	provideMock.GetPendingStorageMock.Return(pendingMock)
   410  
   411  	certificate := testutils.NewCertificateMock(s.T())
   412  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   413  
   414  	mb := testutils.NewMessageBusMock(mc)
   415  	mb.MustRegisterMock.Return()
   416  	jc := testutils.NewJetCoordinatorMock(mc)
   417  
   418  	h := NewMessageHandler(&configuration.Ledger{
   419  		LightChainLimit: 3,
   420  	}, certificate)
   421  	h.JetStorage = s.jetStorage
   422  	h.Nodes = s.nodeStorage
   423  	h.DBContext = s.db
   424  	h.PulseTracker = s.pulseTracker
   425  	h.ObjectStorage = s.objectStorage
   426  
   427  	h.RecentStorageProvider = provideMock
   428  
   429  	delegateType := *genRandomRef(0)
   430  	delegate := *genRandomRef(0)
   431  	objIndex := index.ObjectLifeline{Delegates: map[core.RecordRef]core.RecordRef{delegateType: delegate}}
   432  	msg := message.GetDelegate{
   433  		Head:   *genRandomRef(0),
   434  		AsType: delegateType,
   435  	}
   436  
   437  	mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   438  		if m, ok := gm.(*message.GetObjectIndex); ok {
   439  			assert.Equal(s.T(), msg.Head, m.Object)
   440  			buf, err := index.EncodeObjectLifeline(&objIndex)
   441  			require.NoError(s.T(), err)
   442  			return &reply.ObjectIndex{Index: buf}, nil
   443  		}
   444  
   445  		panic("unexpected call")
   446  	}
   447  
   448  	h.JetCoordinator = jc
   449  	h.Bus = mb
   450  	err := h.Init(s.ctx)
   451  	require.NoError(s.T(), err)
   452  
   453  	heavyRef := genRandomRef(0)
   454  	jc.HeavyMock.Return(heavyRef, nil)
   455  	rep, err := h.handleGetDelegate(contextWithJet(s.ctx, jetID), &message.Parcel{
   456  		Msg: &msg,
   457  	})
   458  	require.NoError(s.T(), err)
   459  	delegateRep, ok := rep.(*reply.Delegate)
   460  	require.True(s.T(), ok)
   461  	assert.Equal(s.T(), delegate, delegateRep.Head)
   462  
   463  	idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Head.Record(), false)
   464  	require.NoError(s.T(), err)
   465  	assert.Equal(s.T(), objIndex.Delegates, idx.Delegates)
   466  }
   467  
   468  func (s *handlerSuite) TestMessageHandler_HandleUpdateObject_FetchesIndexFromHeavy() {
   469  	mc := minimock.NewController(s.T())
   470  	defer mc.Finish()
   471  	jetID := *jet.NewID(0, nil)
   472  
   473  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   474  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   475  
   476  	indexMock.AddObjectMock.Return()
   477  	pendingMock.GetRequestsForObjectMock.Return(nil)
   478  	pendingMock.AddPendingRequestMock.Return()
   479  	pendingMock.RemovePendingRequestMock.Return()
   480  
   481  	provideMock := recentstorage.NewProviderMock(s.T())
   482  	provideMock.GetIndexStorageMock.Return(indexMock)
   483  	provideMock.GetPendingStorageMock.Return(pendingMock)
   484  
   485  	certificate := testutils.NewCertificateMock(s.T())
   486  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   487  
   488  	mb := testutils.NewMessageBusMock(mc)
   489  	mb.MustRegisterMock.Return()
   490  	jc := testutils.NewJetCoordinatorMock(mc)
   491  
   492  	h := NewMessageHandler(&configuration.Ledger{
   493  		LightChainLimit: 3,
   494  	}, certificate)
   495  	h.JetStorage = s.jetStorage
   496  	h.Nodes = s.nodeStorage
   497  	h.DBContext = s.db
   498  	h.PulseTracker = s.pulseTracker
   499  	h.ObjectStorage = s.objectStorage
   500  	h.PlatformCryptographyScheme = s.scheme
   501  	h.RecentStorageProvider = provideMock
   502  
   503  	objIndex := index.ObjectLifeline{LatestState: genRandomID(0), State: record.StateActivation}
   504  	amendRecord := record.ObjectAmendRecord{
   505  		PrevState: *objIndex.LatestState,
   506  	}
   507  	amendHash := s.scheme.ReferenceHasher()
   508  	_, err := amendRecord.WriteHashData(amendHash)
   509  	require.NoError(s.T(), err)
   510  
   511  	msg := message.UpdateObject{
   512  		Record: record.SerializeRecord(&amendRecord),
   513  		Object: *genRandomRef(0),
   514  	}
   515  
   516  	mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   517  		if m, ok := gm.(*message.GetObjectIndex); ok {
   518  			assert.Equal(s.T(), msg.Object, m.Object)
   519  			buf, err := index.EncodeObjectLifeline(&objIndex)
   520  			require.NoError(s.T(), err)
   521  			return &reply.ObjectIndex{Index: buf}, nil
   522  		}
   523  
   524  		panic("unexpected call")
   525  	}
   526  
   527  	h.JetCoordinator = jc
   528  	h.Bus = mb
   529  	err = h.Init(s.ctx)
   530  	require.NoError(s.T(), err)
   531  	heavyRef := genRandomRef(0)
   532  	jc.HeavyMock.Return(heavyRef, nil)
   533  	rep, err := h.handleUpdateObject(contextWithJet(s.ctx, jetID), &message.Parcel{
   534  		Msg:         &msg,
   535  		PulseNumber: core.FirstPulseNumber,
   536  	})
   537  	require.NoError(s.T(), err)
   538  	objRep, ok := rep.(*reply.Object)
   539  	require.True(s.T(), ok)
   540  
   541  	idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Object.Record(), false)
   542  	require.NoError(s.T(), err)
   543  	assert.Equal(s.T(), objRep.State, *idx.LatestState)
   544  }
   545  
   546  func (s *handlerSuite) TestMessageHandler_HandleUpdateObject_UpdateIndexState() {
   547  	// Arrange
   548  	mc := minimock.NewController(s.T())
   549  	defer mc.Finish()
   550  	jetID := *jet.NewID(0, nil)
   551  
   552  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   553  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   554  
   555  	indexMock.AddObjectMock.Return()
   556  	pendingMock.GetRequestsForObjectMock.Return(nil)
   557  	pendingMock.AddPendingRequestMock.Return()
   558  	pendingMock.RemovePendingRequestMock.Return()
   559  
   560  	provideMock := recentstorage.NewProviderMock(s.T())
   561  	provideMock.GetIndexStorageMock.Return(indexMock)
   562  	provideMock.GetPendingStorageMock.Return(pendingMock)
   563  
   564  	certificate := testutils.NewCertificateMock(s.T())
   565  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   566  
   567  	h := NewMessageHandler(&configuration.Ledger{
   568  		LightChainLimit: 3,
   569  	}, certificate)
   570  	h.JetStorage = s.jetStorage
   571  	h.Nodes = s.nodeStorage
   572  	h.DBContext = s.db
   573  	h.PulseTracker = s.pulseTracker
   574  	h.ObjectStorage = s.objectStorage
   575  	h.RecentStorageProvider = provideMock
   576  	h.PlatformCryptographyScheme = s.scheme
   577  
   578  	objIndex := index.ObjectLifeline{
   579  		LatestState:  genRandomID(0),
   580  		State:        record.StateActivation,
   581  		LatestUpdate: 0,
   582  	}
   583  	amendRecord := record.ObjectAmendRecord{
   584  		PrevState: *objIndex.LatestState,
   585  	}
   586  	amendHash := s.scheme.ReferenceHasher()
   587  	_, err := amendRecord.WriteHashData(amendHash)
   588  	require.NoError(s.T(), err)
   589  
   590  	msg := message.UpdateObject{
   591  		Record: record.SerializeRecord(&amendRecord),
   592  		Object: *genRandomRef(0),
   593  	}
   594  	err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Object.Record(), &objIndex)
   595  	require.NoError(s.T(), err)
   596  
   597  	// Act
   598  	rep, err := h.handleUpdateObject(contextWithJet(s.ctx, jetID), &message.Parcel{
   599  		Msg:         &msg,
   600  		PulseNumber: core.FirstPulseNumber,
   601  	})
   602  	require.NoError(s.T(), err)
   603  	_, ok := rep.(*reply.Object)
   604  	require.True(s.T(), ok)
   605  
   606  	// Arrange
   607  	idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Object.Record(), false)
   608  	require.NoError(s.T(), err)
   609  	require.Equal(s.T(), core.FirstPulseNumber, int(idx.LatestUpdate))
   610  }
   611  
   612  func (s *handlerSuite) TestMessageHandler_HandleGetObjectIndex() {
   613  	mc := minimock.NewController(s.T())
   614  	defer mc.Finish()
   615  	jetID := *jet.NewID(0, nil)
   616  	msg := message.GetObjectIndex{
   617  		Object: *genRandomRef(0),
   618  	}
   619  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   620  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   621  
   622  	indexMock.AddObjectMock.Return()
   623  	pendingMock.GetRequestsForObjectMock.Return(nil)
   624  	pendingMock.AddPendingRequestMock.Return()
   625  	pendingMock.RemovePendingRequestMock.Return()
   626  
   627  	provideMock := recentstorage.NewProviderMock(s.T())
   628  	provideMock.GetIndexStorageMock.Return(indexMock)
   629  	provideMock.GetPendingStorageMock.Return(pendingMock)
   630  
   631  	certificate := testutils.NewCertificateMock(s.T())
   632  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   633  
   634  	jc := testutils.NewJetCoordinatorMock(mc)
   635  
   636  	mb := testutils.NewMessageBusMock(mc)
   637  	mb.MustRegisterMock.Return()
   638  
   639  	h := NewMessageHandler(&configuration.Ledger{
   640  		LightChainLimit: 3,
   641  	}, certificate)
   642  	h.JetCoordinator = jc
   643  	h.Bus = mb
   644  	h.JetStorage = s.jetStorage
   645  	h.Nodes = s.nodeStorage
   646  	h.DBContext = s.db
   647  	h.PulseTracker = s.pulseTracker
   648  	h.ObjectStorage = s.objectStorage
   649  
   650  	err := h.Init(s.ctx)
   651  	require.NoError(s.T(), err)
   652  
   653  	h.RecentStorageProvider = provideMock
   654  
   655  	objectIndex := index.ObjectLifeline{LatestState: genRandomID(0)}
   656  	err = s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Object.Record(), &objectIndex)
   657  	require.NoError(s.T(), err)
   658  
   659  	rep, err := h.handleGetObjectIndex(contextWithJet(s.ctx, jetID), &message.Parcel{
   660  		Msg: &msg,
   661  	})
   662  	require.NoError(s.T(), err)
   663  	indexRep, ok := rep.(*reply.ObjectIndex)
   664  	require.True(s.T(), ok)
   665  	decodedIndex, err := index.DecodeObjectLifeline(indexRep.Index)
   666  	require.NoError(s.T(), err)
   667  	assert.Equal(s.T(), objectIndex, *decodedIndex)
   668  }
   669  
   670  func (s *handlerSuite) TestMessageHandler_HandleHasPendingRequests() {
   671  	mc := minimock.NewController(s.T())
   672  	defer mc.Finish()
   673  	msg := message.GetPendingRequests{
   674  		Object: *genRandomRef(0),
   675  	}
   676  	pendingRequests := []core.RecordID{
   677  		*genRandomID(core.FirstPulseNumber),
   678  		*genRandomID(core.FirstPulseNumber),
   679  	}
   680  
   681  	recentStorageMock := recentstorage.NewPendingStorageMock(s.T())
   682  	recentStorageMock.GetRequestsForObjectMock.Return(pendingRequests)
   683  
   684  	certificate := testutils.NewCertificateMock(s.T())
   685  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   686  
   687  	jetID := *jet.NewID(0, nil)
   688  	jc := testutils.NewJetCoordinatorMock(mc)
   689  	mb := testutils.NewMessageBusMock(mc)
   690  	mb.MustRegisterMock.Return()
   691  
   692  	h := NewMessageHandler(&configuration.Ledger{}, certificate)
   693  	h.JetCoordinator = jc
   694  	h.Bus = mb
   695  	h.JetStorage = s.jetStorage
   696  	h.Nodes = s.nodeStorage
   697  	h.DBContext = s.db
   698  	h.PulseTracker = s.pulseTracker
   699  	h.ObjectStorage = s.objectStorage
   700  
   701  	err := h.Init(s.ctx)
   702  	require.NoError(s.T(), err)
   703  
   704  	provideMock := recentstorage.NewProviderMock(s.T())
   705  	provideMock.GetPendingStorageMock.Return(recentStorageMock)
   706  
   707  	h.RecentStorageProvider = provideMock
   708  
   709  	rep, err := h.handleHasPendingRequests(contextWithJet(s.ctx, jetID), &message.Parcel{
   710  		Msg:         &msg,
   711  		PulseNumber: core.FirstPulseNumber + 1,
   712  	})
   713  	require.NoError(s.T(), err)
   714  	has, ok := rep.(*reply.HasPendingRequests)
   715  	require.True(s.T(), ok)
   716  	assert.True(s.T(), has.Has)
   717  }
   718  
   719  func (s *handlerSuite) TestMessageHandler_HandleGetCode_Redirects() {
   720  	mc := minimock.NewController(s.T())
   721  	defer mc.Finish()
   722  
   723  	tf := testutils.NewDelegationTokenFactoryMock(mc)
   724  	jc := testutils.NewJetCoordinatorMock(mc)
   725  	mb := testutils.NewMessageBusMock(mc)
   726  	mb.MustRegisterMock.Return()
   727  
   728  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   729  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   730  
   731  	indexMock.AddObjectMock.Return()
   732  	pendingMock.GetRequestsForObjectMock.Return(nil)
   733  	pendingMock.AddPendingRequestMock.Return()
   734  	pendingMock.RemovePendingRequestMock.Return()
   735  
   736  	provideMock := recentstorage.NewProviderMock(s.T())
   737  	provideMock.GetIndexStorageMock.Return(indexMock)
   738  	provideMock.GetPendingStorageMock.Return(pendingMock)
   739  
   740  	certificate := testutils.NewCertificateMock(s.T())
   741  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   742  
   743  	tf.IssueGetCodeRedirectMock.Return(&delegationtoken.GetCodeRedirectToken{Signature: []byte{1, 2, 3}}, nil)
   744  
   745  	h := NewMessageHandler(&configuration.Ledger{
   746  		LightChainLimit: 2,
   747  	}, certificate)
   748  	h.JetCoordinator = jc
   749  	h.DelegationTokenFactory = tf
   750  	h.Bus = mb
   751  	h.JetStorage = s.jetStorage
   752  	h.Nodes = s.nodeStorage
   753  	h.DBContext = s.db
   754  	h.PulseTracker = s.pulseTracker
   755  	h.ObjectStorage = s.objectStorage
   756  	err := h.Init(s.ctx)
   757  	require.NoError(s.T(), err)
   758  
   759  	h.RecentStorageProvider = provideMock
   760  
   761  	jetID := *jet.NewID(0, nil)
   762  	msg := message.GetCode{
   763  		Code: *genRandomRef(core.FirstPulseNumber),
   764  	}
   765  
   766  	s.T().Run("redirects to light before limit threshold", func(t *testing.T) {
   767  		err := s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 1})
   768  		require.NoError(t, err)
   769  		lightRef := genRandomRef(0)
   770  		jc.NodeForJetMock.Return(lightRef, nil)
   771  		rep, err := h.handleGetCode(s.ctx, &message.Parcel{
   772  			Msg:         &msg,
   773  			PulseNumber: core.FirstPulseNumber + 1,
   774  		})
   775  		require.NoError(t, err)
   776  		redirect, ok := rep.(*reply.GetCodeRedirectReply)
   777  		require.True(t, ok)
   778  		token, ok := redirect.Token.(*delegationtoken.GetCodeRedirectToken)
   779  		assert.Equal(t, []byte{1, 2, 3}, token.Signature)
   780  		assert.Equal(t, lightRef, redirect.GetReceiver())
   781  	})
   782  
   783  	s.T().Run("redirects to heavy after limit threshold", func(t *testing.T) {
   784  		err = s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 2})
   785  		require.NoError(t, err)
   786  		heavyRef := genRandomRef(0)
   787  		jc.NodeForJetMock.Return(heavyRef, nil)
   788  		rep, err := h.handleGetCode(contextWithJet(s.ctx, jetID), &message.Parcel{
   789  			Msg:         &msg,
   790  			PulseNumber: core.FirstPulseNumber + 2,
   791  		})
   792  		require.NoError(t, err)
   793  		redirect, ok := rep.(*reply.GetCodeRedirectReply)
   794  		require.True(t, ok)
   795  		token, ok := redirect.Token.(*delegationtoken.GetCodeRedirectToken)
   796  		assert.Equal(t, []byte{1, 2, 3}, token.Signature)
   797  		assert.Equal(t, heavyRef, redirect.GetReceiver())
   798  	})
   799  }
   800  
   801  func (s *handlerSuite) TestMessageHandler_HandleRegisterChild_FetchesIndexFromHeavy() {
   802  	mc := minimock.NewController(s.T())
   803  	defer mc.Finish()
   804  	jetID := *jet.NewID(0, nil)
   805  
   806  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   807  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   808  
   809  	indexMock.AddObjectMock.Return()
   810  	pendingMock.GetRequestsForObjectMock.Return(nil)
   811  	pendingMock.AddPendingRequestMock.Return()
   812  	pendingMock.RemovePendingRequestMock.Return()
   813  
   814  	provideMock := recentstorage.NewProviderMock(s.T())
   815  	provideMock.GetIndexStorageMock.Return(indexMock)
   816  	provideMock.GetPendingStorageMock.Return(pendingMock)
   817  
   818  	certificate := testutils.NewCertificateMock(s.T())
   819  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   820  
   821  	mb := testutils.NewMessageBusMock(mc)
   822  	mb.MustRegisterMock.Return()
   823  	jc := testutils.NewJetCoordinatorMock(mc)
   824  	h := NewMessageHandler(&configuration.Ledger{
   825  		LightChainLimit: 2,
   826  	}, certificate)
   827  	h.JetStorage = s.jetStorage
   828  	h.Nodes = s.nodeStorage
   829  	h.DBContext = s.db
   830  	h.PulseTracker = s.pulseTracker
   831  	h.ObjectStorage = s.objectStorage
   832  	h.RecentStorageProvider = provideMock
   833  	h.PlatformCryptographyScheme = s.scheme
   834  
   835  	objIndex := index.ObjectLifeline{LatestState: genRandomID(0), State: record.StateActivation}
   836  	childRecord := record.ChildRecord{
   837  		Ref:       *genRandomRef(0),
   838  		PrevChild: nil,
   839  	}
   840  	amendHash := s.scheme.ReferenceHasher()
   841  	_, err := childRecord.WriteHashData(amendHash)
   842  	require.NoError(s.T(), err)
   843  	childID := core.NewRecordID(0, amendHash.Sum(nil))
   844  
   845  	msg := message.RegisterChild{
   846  		Record: record.SerializeRecord(&childRecord),
   847  		Parent: *genRandomRef(0),
   848  	}
   849  
   850  	mb.SendFunc = func(c context.Context, gm core.Message, o *core.MessageSendOptions) (r core.Reply, r1 error) {
   851  		if m, ok := gm.(*message.GetObjectIndex); ok {
   852  			assert.Equal(s.T(), msg.Parent, m.Object)
   853  			buf, err := index.EncodeObjectLifeline(&objIndex)
   854  			require.NoError(s.T(), err)
   855  			return &reply.ObjectIndex{Index: buf}, nil
   856  		}
   857  
   858  		panic("unexpected call")
   859  	}
   860  
   861  	h.JetCoordinator = jc
   862  	h.Bus = mb
   863  	err = h.Init(s.ctx)
   864  	require.NoError(s.T(), err)
   865  	heavyRef := genRandomRef(0)
   866  	jc.HeavyMock.Return(heavyRef, nil)
   867  	rep, err := h.handleRegisterChild(contextWithJet(s.ctx, jetID), &message.Parcel{
   868  		Msg: &msg,
   869  	})
   870  	require.NoError(s.T(), err)
   871  	objRep, ok := rep.(*reply.ID)
   872  	require.True(s.T(), ok)
   873  	assert.Equal(s.T(), *childID, objRep.ID)
   874  
   875  	idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Parent.Record(), false)
   876  	require.NoError(s.T(), err)
   877  	assert.Equal(s.T(), childID, idx.ChildPointer)
   878  }
   879  
   880  func (s *handlerSuite) TestMessageHandler_HandleRegisterChild_IndexStateUpdated() {
   881  	// Arrange
   882  	mc := minimock.NewController(s.T())
   883  	defer mc.Finish()
   884  	jetID := *jet.NewID(0, nil)
   885  
   886  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
   887  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
   888  
   889  	indexMock.AddObjectMock.Return()
   890  	pendingMock.GetRequestsForObjectMock.Return(nil)
   891  	pendingMock.AddPendingRequestMock.Return()
   892  	pendingMock.RemovePendingRequestMock.Return()
   893  
   894  	provideMock := recentstorage.NewProviderMock(s.T())
   895  	provideMock.GetIndexStorageMock.Return(indexMock)
   896  	provideMock.GetPendingStorageMock.Return(pendingMock)
   897  
   898  	certificate := testutils.NewCertificateMock(s.T())
   899  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
   900  
   901  	h := NewMessageHandler(&configuration.Ledger{
   902  		LightChainLimit: 2,
   903  	}, certificate)
   904  	h.JetStorage = s.jetStorage
   905  	h.Nodes = s.nodeStorage
   906  	h.DBContext = s.db
   907  	h.PulseTracker = s.pulseTracker
   908  	h.ObjectStorage = s.objectStorage
   909  	h.RecentStorageProvider = provideMock
   910  	h.PlatformCryptographyScheme = s.scheme
   911  
   912  	objIndex := index.ObjectLifeline{
   913  		LatestState:  genRandomID(0),
   914  		State:        record.StateActivation,
   915  		LatestUpdate: core.FirstPulseNumber,
   916  	}
   917  	childRecord := record.ChildRecord{
   918  		Ref:       *genRandomRef(0),
   919  		PrevChild: nil,
   920  	}
   921  	msg := message.RegisterChild{
   922  		Record: record.SerializeRecord(&childRecord),
   923  		Parent: *genRandomRef(0),
   924  	}
   925  
   926  	err := s.objectStorage.SetObjectIndex(s.ctx, jetID, msg.Parent.Record(), &objIndex)
   927  	require.NoError(s.T(), err)
   928  
   929  	// Act
   930  	_, err = h.handleRegisterChild(contextWithJet(s.ctx, jetID), &message.Parcel{
   931  		Msg:         &msg,
   932  		PulseNumber: core.FirstPulseNumber + 100,
   933  	})
   934  	require.NoError(s.T(), err)
   935  
   936  	// Assert
   937  	idx, err := s.objectStorage.GetObjectIndex(s.ctx, jetID, msg.Parent.Record(), false)
   938  	require.NoError(s.T(), err)
   939  	require.Equal(s.T(), int(idx.LatestUpdate), core.FirstPulseNumber+100)
   940  }
   941  
   942  const testDropSize uint64 = 100
   943  
   944  func addDropSizeToDB(s *handlerSuite, jetID core.RecordID) {
   945  	dropSizeData := &jet.DropSize{
   946  		JetID:    jetID,
   947  		PulseNo:  core.FirstPulseNumber,
   948  		DropSize: testDropSize,
   949  	}
   950  
   951  	cryptoServiceMock := testutils.NewCryptographyServiceMock(s.T())
   952  	cryptoServiceMock.SignFunc = func(p []byte) (r *core.Signature, r1 error) {
   953  		signature := core.SignatureFromBytes(nil)
   954  		return &signature, nil
   955  	}
   956  
   957  	hasher := platformpolicy.NewPlatformCryptographyScheme().IntegrityHasher()
   958  	_, err := dropSizeData.WriteHashData(hasher)
   959  	require.NoError(s.T(), err)
   960  
   961  	signature, err := cryptoServiceMock.Sign(hasher.Sum(nil))
   962  	require.NoError(s.T(), err)
   963  
   964  	dropSizeData.Signature = signature.Bytes()
   965  
   966  	err = s.dropStorage.AddDropSize(s.ctx, dropSizeData)
   967  	require.NoError(s.T(), err)
   968  }
   969  
   970  func (s *handlerSuite) TestMessageHandler_HandleHotRecords() {
   971  	mc := minimock.NewController(s.T())
   972  	jetID := testutils.RandomJet()
   973  
   974  	err := s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: core.FirstPulseNumber + 1})
   975  	require.NoError(s.T(), err)
   976  
   977  	jc := testutils.NewJetCoordinatorMock(mc)
   978  
   979  	firstID := core.NewRecordID(core.FirstPulseNumber, []byte{1, 2, 3})
   980  	secondID := record.NewRecordIDFromRecord(s.scheme, core.FirstPulseNumber, &record.CodeRecord{})
   981  	thirdID := record.NewRecordIDFromRecord(s.scheme, core.FirstPulseNumber-1, &record.CodeRecord{})
   982  
   983  	mb := testutils.NewMessageBusMock(mc)
   984  	mb.MustRegisterMock.Return()
   985  	mb.SendFunc = func(p context.Context, p1 core.Message, p2 *core.MessageSendOptions) (r core.Reply, r1 error) {
   986  		parsedMsg, ok := p1.(*message.AbandonedRequestsNotification)
   987  		require.Equal(s.T(), true, ok)
   988  		require.Equal(s.T(), *secondID, parsedMsg.Object)
   989  		return &reply.OK{}, nil
   990  	}
   991  
   992  	firstIndex, _ := index.EncodeObjectLifeline(&index.ObjectLifeline{
   993  		LatestState: firstID,
   994  	})
   995  	err = s.objectStorage.SetObjectIndex(s.ctx, jetID, firstID, &index.ObjectLifeline{
   996  		LatestState: firstID,
   997  	})
   998  
   999  	dropSizeHistory, err := s.dropStorage.GetDropSizeHistory(s.ctx, jetID)
  1000  	require.NoError(s.T(), err)
  1001  	require.Equal(s.T(), jet.DropSizeHistory{}, dropSizeHistory)
  1002  	addDropSizeToDB(s, jetID)
  1003  
  1004  	dropSizeHistory, err = s.dropStorage.GetDropSizeHistory(s.ctx, jetID)
  1005  	require.NoError(s.T(), err)
  1006  
  1007  	hotIndexes := &message.HotData{
  1008  		Jet:         *core.NewRecordRef(core.DomainID, jetID),
  1009  		PulseNumber: core.FirstPulseNumber,
  1010  		RecentObjects: map[core.RecordID]message.HotIndex{
  1011  			*firstID: {
  1012  				Index: firstIndex,
  1013  				TTL:   320,
  1014  			},
  1015  		},
  1016  		PendingRequests: map[core.RecordID]recentstorage.PendingObjectContext{
  1017  			*secondID: {},
  1018  			*thirdID:  {Active: true},
  1019  		},
  1020  		Drop:               jet.JetDrop{Pulse: core.FirstPulseNumber, Hash: []byte{88}},
  1021  		DropJet:            jetID,
  1022  		JetDropSizeHistory: dropSizeHistory,
  1023  	}
  1024  
  1025  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
  1026  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
  1027  
  1028  	pendingMock.SetContextToObjectFunc = func(p context.Context, p1 core.RecordID, p2 recentstorage.PendingObjectContext) {
  1029  
  1030  		if bytes.Equal(p1.Bytes(), secondID.Bytes()) {
  1031  			require.Equal(s.T(), false, p2.Active)
  1032  			return
  1033  		}
  1034  		if bytes.Equal(p1.Bytes(), thirdID.Bytes()) {
  1035  			require.Equal(s.T(), false, p2.Active)
  1036  			return
  1037  		}
  1038  		s.T().Fail()
  1039  	}
  1040  	indexMock.AddObjectWithTLLFunc = func(ctx context.Context, p core.RecordID, ttl int) {
  1041  		require.Equal(s.T(), p, *firstID)
  1042  		require.Equal(s.T(), 320, ttl)
  1043  	}
  1044  	provideMock := recentstorage.NewProviderMock(s.T())
  1045  	provideMock.GetPendingStorageMock.Return(pendingMock)
  1046  	provideMock.GetIndexStorageMock.Return(indexMock)
  1047  
  1048  	certificate := testutils.NewCertificateMock(s.T())
  1049  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
  1050  
  1051  	h := NewMessageHandler(&configuration.Ledger{}, certificate)
  1052  	h.JetCoordinator = jc
  1053  	h.RecentStorageProvider = provideMock
  1054  	h.Bus = mb
  1055  	h.JetStorage = s.jetStorage
  1056  	h.Nodes = s.nodeStorage
  1057  	h.DBContext = s.db
  1058  	h.PulseTracker = s.pulseTracker
  1059  	h.ObjectStorage = s.objectStorage
  1060  	h.DropStorage = s.dropStorage
  1061  
  1062  	err = h.Init(s.ctx)
  1063  	require.NoError(s.T(), err)
  1064  
  1065  	res, err := h.handleHotRecords(s.ctx, &message.Parcel{Msg: hotIndexes})
  1066  
  1067  	require.NoError(s.T(), err)
  1068  	require.Equal(s.T(), res, &reply.OK{})
  1069  
  1070  	savedDrop, err := h.DropStorage.GetDrop(s.ctx, jetID, core.FirstPulseNumber)
  1071  	require.NoError(s.T(), err)
  1072  	require.Equal(s.T(), &jet.JetDrop{Pulse: core.FirstPulseNumber, Hash: []byte{88}}, savedDrop)
  1073  
  1074  	// check drop size list
  1075  	dropSizeHistory, err = s.dropStorage.GetDropSizeHistory(s.ctx, jetID)
  1076  	require.NoError(s.T(), err)
  1077  	require.Equal(s.T(), testDropSize, dropSizeHistory[0].DropSize)
  1078  	require.Equal(s.T(), jetID, dropSizeHistory[0].JetID)
  1079  	require.Equal(s.T(), core.FirstPulseNumber, int(dropSizeHistory[0].PulseNo))
  1080  
  1081  	indexMock.MinimockFinish()
  1082  	pendingMock.MinimockFinish()
  1083  }
  1084  
  1085  func (s *handlerSuite) TestMessageHandler_HandleValidationCheck() {
  1086  	mc := minimock.NewController(s.T())
  1087  	defer mc.Finish()
  1088  	jetID := *jet.NewID(0, nil)
  1089  
  1090  	indexMock := recentstorage.NewRecentIndexStorageMock(s.T())
  1091  	pendingMock := recentstorage.NewPendingStorageMock(s.T())
  1092  
  1093  	indexMock.AddObjectMock.Return()
  1094  	pendingMock.AddPendingRequestMock.Return()
  1095  	pendingMock.RemovePendingRequestMock.Return()
  1096  
  1097  	provideMock := recentstorage.NewProviderMock(s.T())
  1098  	provideMock.GetIndexStorageMock.Return(indexMock)
  1099  	provideMock.GetPendingStorageMock.Return(pendingMock)
  1100  
  1101  	nodeMock := network.NewNodeMock(s.T())
  1102  	nodeMock.RoleMock.Return(core.StaticRoleLightMaterial)
  1103  	nodeNetworkMock := network.NewNodeNetworkMock(s.T())
  1104  	nodeNetworkMock.GetOriginMock.Return(nodeMock)
  1105  
  1106  	jc := testutils.NewJetCoordinatorMock(mc)
  1107  
  1108  	certificate := testutils.NewCertificateMock(s.T())
  1109  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
  1110  
  1111  	mb := testutils.NewMessageBusMock(mc)
  1112  	mb.MustRegisterMock.Return()
  1113  	h := NewMessageHandler(&configuration.Ledger{
  1114  		LightChainLimit: 3,
  1115  	}, certificate)
  1116  	h.JetCoordinator = jc
  1117  	h.Bus = mb
  1118  	h.JetStorage = s.jetStorage
  1119  	h.Nodes = s.nodeStorage
  1120  	h.DBContext = s.db
  1121  	h.PulseTracker = s.pulseTracker
  1122  	h.ObjectStorage = s.objectStorage
  1123  	h.RecentStorageProvider = provideMock
  1124  
  1125  	err := h.Init(s.ctx)
  1126  	require.NoError(s.T(), err)
  1127  
  1128  	s.T().Run("returns not ok when not valid", func(t *testing.T) {
  1129  		validatedStateID, err := s.objectStorage.SetRecord(s.ctx, jetID, 0, &record.ObjectAmendRecord{})
  1130  		require.NoError(t, err)
  1131  
  1132  		msg := message.ValidationCheck{
  1133  			Object:              *genRandomRef(0),
  1134  			ValidatedState:      *validatedStateID,
  1135  			LatestStateApproved: genRandomID(0),
  1136  		}
  1137  
  1138  		rep, err := h.handleValidationCheck(contextWithJet(s.ctx, jetID), &message.Parcel{
  1139  			Msg: &msg,
  1140  		})
  1141  		require.NoError(t, err)
  1142  		_, ok := rep.(*reply.NotOK)
  1143  		assert.True(t, ok)
  1144  	})
  1145  
  1146  	s.T().Run("returns ok when valid", func(t *testing.T) {
  1147  		approvedStateID := *genRandomID(0)
  1148  		validatedStateID, err := s.objectStorage.SetRecord(s.ctx, jetID, 0, &record.ObjectAmendRecord{
  1149  			PrevState: approvedStateID,
  1150  		})
  1151  		require.NoError(t, err)
  1152  
  1153  		msg := message.ValidationCheck{
  1154  			Object:              *genRandomRef(0),
  1155  			ValidatedState:      *validatedStateID,
  1156  			LatestStateApproved: &approvedStateID,
  1157  		}
  1158  
  1159  		rep, err := h.handleValidationCheck(contextWithJet(s.ctx, jetID), &message.Parcel{
  1160  			Msg: &msg,
  1161  		})
  1162  		require.NoError(t, err)
  1163  		_, ok := rep.(*reply.OK)
  1164  		assert.True(t, ok)
  1165  	})
  1166  }
  1167  
  1168  func (s *handlerSuite) TestMessageHandler_HandleJetDrop_SaveJet() {
  1169  	// Arrange
  1170  	mc := minimock.NewController(s.T())
  1171  	defer mc.Finish()
  1172  
  1173  	jetID := jet.NewID(0, []byte{2})
  1174  	msg := message.JetDrop{
  1175  		JetID: *jetID,
  1176  	}
  1177  	expectedSetId := jet.IDSet{
  1178  		*jetID: struct{}{},
  1179  	}
  1180  
  1181  	certificate := testutils.NewCertificateMock(s.T())
  1182  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
  1183  
  1184  	h := NewMessageHandler(&configuration.Ledger{
  1185  		LightChainLimit: 3,
  1186  	}, certificate)
  1187  	h.JetStorage = s.jetStorage
  1188  	h.Nodes = s.nodeStorage
  1189  	h.DBContext = s.db
  1190  	h.PulseTracker = s.pulseTracker
  1191  	h.ObjectStorage = s.objectStorage
  1192  
  1193  	// Act
  1194  	response, err := h.handleJetDrop(s.ctx, &message.Parcel{Msg: &msg})
  1195  	require.NoError(s.T(), err)
  1196  
  1197  	idSet, err := s.jetStorage.GetJets(s.ctx)
  1198  	require.NoError(s.T(), err)
  1199  	require.NotNil(s.T(), idSet)
  1200  
  1201  	// Assert
  1202  	require.Equal(s.T(), &reply.OK{}, response)
  1203  	for id := range expectedSetId {
  1204  		require.True(s.T(), idSet.Has(id))
  1205  	}
  1206  }
  1207  
  1208  func (s *handlerSuite) TestMessageHandler_HandleJetDrop_SaveJet_ExistingMap() {
  1209  	// Arrange
  1210  	// ctx := inslogger.TestContext(t)
  1211  	mc := minimock.NewController(s.T())
  1212  	// db, cleaner := storagetest.TmpDB(ctx, t)
  1213  	defer mc.Finish()
  1214  
  1215  	jetID := jet.NewID(0, []byte{2})
  1216  	secondJetID := jet.NewID(0, []byte{3})
  1217  	msg := message.JetDrop{
  1218  		JetID: *jetID,
  1219  	}
  1220  	secondMsg := message.JetDrop{
  1221  		JetID: *secondJetID,
  1222  	}
  1223  	expectedSetId := jet.IDSet{
  1224  		*jetID:       struct{}{},
  1225  		*secondJetID: struct{}{},
  1226  	}
  1227  
  1228  	certificate := testutils.NewCertificateMock(s.T())
  1229  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
  1230  
  1231  	h := NewMessageHandler(&configuration.Ledger{
  1232  		LightChainLimit: 3,
  1233  	}, certificate)
  1234  	h.JetStorage = s.jetStorage
  1235  	h.Nodes = s.nodeStorage
  1236  	h.DBContext = s.db
  1237  	h.PulseTracker = s.pulseTracker
  1238  	h.ObjectStorage = s.objectStorage
  1239  
  1240  	// Act
  1241  	response, err := h.handleJetDrop(s.ctx, &message.Parcel{Msg: &msg})
  1242  	require.NoError(s.T(), err)
  1243  	require.Equal(s.T(), &reply.OK{}, response)
  1244  
  1245  	secondResponse, err := h.handleJetDrop(s.ctx, &message.Parcel{Msg: &secondMsg})
  1246  	require.NoError(s.T(), err)
  1247  	require.Equal(s.T(), &reply.OK{}, secondResponse)
  1248  
  1249  	idSet, err := s.jetStorage.GetJets(s.ctx)
  1250  	require.NoError(s.T(), err)
  1251  	require.NotNil(s.T(), idSet)
  1252  
  1253  	// Assert
  1254  	for id := range expectedSetId {
  1255  		require.True(s.T(), idSet.Has(id))
  1256  	}
  1257  }
  1258  
  1259  func (s *handlerSuite) TestMessageHandler_HandleGetRequest() {
  1260  	mc := minimock.NewController(s.T())
  1261  	defer mc.Finish()
  1262  
  1263  	jetID := *jet.NewID(0, nil)
  1264  
  1265  	req := record.RequestRecord{
  1266  		MessageHash: []byte{1, 2, 3},
  1267  		Object:      *genRandomID(0),
  1268  	}
  1269  	reqID, err := s.objectStorage.SetRecord(s.ctx, jetID, core.FirstPulseNumber, &req)
  1270  
  1271  	msg := message.GetRequest{
  1272  		Request: *reqID,
  1273  	}
  1274  	certificate := testutils.NewCertificateMock(s.T())
  1275  	certificate.GetRoleMock.Return(core.StaticRoleLightMaterial)
  1276  
  1277  	h := NewMessageHandler(&configuration.Ledger{}, certificate)
  1278  	h.ObjectStorage = s.objectStorage
  1279  
  1280  	rep, err := h.handleGetRequest(contextWithJet(s.ctx, jetID), &message.Parcel{
  1281  		Msg:         &msg,
  1282  		PulseNumber: core.FirstPulseNumber + 1,
  1283  	})
  1284  	require.NoError(s.T(), err)
  1285  	reqReply, ok := rep.(*reply.Request)
  1286  	require.True(s.T(), ok)
  1287  	assert.Equal(s.T(), req, *record.DeserializeRecord(reqReply.Record).(*record.RequestRecord))
  1288  }