github.com/MetalBlockchain/metalgo@v1.11.9/snow/engine/common/test_engine.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package common
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/MetalBlockchain/metalgo/ids"
    15  	"github.com/MetalBlockchain/metalgo/snow"
    16  	"github.com/MetalBlockchain/metalgo/utils/set"
    17  	"github.com/MetalBlockchain/metalgo/version"
    18  )
    19  
    20  var (
    21  	errTimeout                       = errors.New("unexpectedly called Timeout")
    22  	errGossip                        = errors.New("unexpectedly called Gossip")
    23  	errNotify                        = errors.New("unexpectedly called Notify")
    24  	errGetStateSummaryFrontier       = errors.New("unexpectedly called GetStateSummaryFrontier")
    25  	errGetStateSummaryFrontierFailed = errors.New("unexpectedly called GetStateSummaryFrontierFailed")
    26  	errStateSummaryFrontier          = errors.New("unexpectedly called StateSummaryFrontier")
    27  	errGetAcceptedStateSummary       = errors.New("unexpectedly called GetAcceptedStateSummary")
    28  	errGetAcceptedStateSummaryFailed = errors.New("unexpectedly called GetAcceptedStateSummaryFailed")
    29  	errAcceptedStateSummary          = errors.New("unexpectedly called AcceptedStateSummary")
    30  	errGetAcceptedFrontier           = errors.New("unexpectedly called GetAcceptedFrontier")
    31  	errGetAcceptedFrontierFailed     = errors.New("unexpectedly called GetAcceptedFrontierFailed")
    32  	errAcceptedFrontier              = errors.New("unexpectedly called AcceptedFrontier")
    33  	errGetAccepted                   = errors.New("unexpectedly called GetAccepted")
    34  	errGetAcceptedFailed             = errors.New("unexpectedly called GetAcceptedFailed")
    35  	errAccepted                      = errors.New("unexpectedly called Accepted")
    36  	errGet                           = errors.New("unexpectedly called Get")
    37  	errGetAncestors                  = errors.New("unexpectedly called GetAncestors")
    38  	errGetFailed                     = errors.New("unexpectedly called GetFailed")
    39  	errGetAncestorsFailed            = errors.New("unexpectedly called GetAncestorsFailed")
    40  	errPut                           = errors.New("unexpectedly called Put")
    41  	errAncestors                     = errors.New("unexpectedly called Ancestors")
    42  	errPushQuery                     = errors.New("unexpectedly called PushQuery")
    43  	errPullQuery                     = errors.New("unexpectedly called PullQuery")
    44  	errQueryFailed                   = errors.New("unexpectedly called QueryFailed")
    45  	errChits                         = errors.New("unexpectedly called Chits")
    46  	errStart                         = errors.New("unexpectedly called Start")
    47  
    48  	_ Engine = (*EngineTest)(nil)
    49  )
    50  
    51  // EngineTest is a test engine
    52  type EngineTest struct {
    53  	T *testing.T
    54  
    55  	CantStart,
    56  
    57  	CantIsBootstrapped,
    58  	CantTimeout,
    59  	CantGossip,
    60  	CantHalt,
    61  	CantShutdown,
    62  
    63  	CantContext,
    64  
    65  	CantNotify,
    66  
    67  	CantGetStateSummaryFrontier,
    68  	CantGetStateSummaryFrontierFailed,
    69  	CantStateSummaryFrontier,
    70  
    71  	CantGetAcceptedStateSummary,
    72  	CantGetAcceptedStateSummaryFailed,
    73  	CantAcceptedStateSummary,
    74  
    75  	CantGetAcceptedFrontier,
    76  	CantGetAcceptedFrontierFailed,
    77  	CantAcceptedFrontier,
    78  
    79  	CantGetAccepted,
    80  	CantGetAcceptedFailed,
    81  	CantAccepted,
    82  
    83  	CantGet,
    84  	CantGetAncestors,
    85  	CantGetFailed,
    86  	CantGetAncestorsFailed,
    87  	CantPut,
    88  	CantAncestors,
    89  
    90  	CantPushQuery,
    91  	CantPullQuery,
    92  	CantQueryFailed,
    93  	CantChits,
    94  
    95  	CantConnected,
    96  	CantDisconnected,
    97  
    98  	CantHealth,
    99  
   100  	CantCrossChainAppRequest,
   101  	CantCrossChainAppRequestFailed,
   102  	CantCrossChainAppResponse,
   103  
   104  	CantAppRequest,
   105  	CantAppResponse,
   106  	CantAppGossip,
   107  	CantAppRequestFailed,
   108  
   109  	CantGetVM bool
   110  
   111  	StartF                       func(ctx context.Context, startReqID uint32) error
   112  	IsBootstrappedF              func() bool
   113  	ContextF                     func() *snow.ConsensusContext
   114  	HaltF                        func(context.Context)
   115  	TimeoutF, GossipF, ShutdownF func(context.Context) error
   116  	NotifyF                      func(context.Context, Message) error
   117  	GetF, GetAncestorsF          func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error
   118  	PullQueryF                   func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID, requestedHeight uint64) error
   119  	PutF                         func(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte) error
   120  	PushQueryF                   func(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte, requestedHeight uint64) error
   121  	AncestorsF                   func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containers [][]byte) error
   122  	AcceptedFrontierF            func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error
   123  	GetAcceptedF, AcceptedF      func(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredIDs set.Set[ids.ID]) error
   124  	ChitsF                       func(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error
   125  	GetStateSummaryFrontierF, GetStateSummaryFrontierFailedF, GetAcceptedStateSummaryFailedF,
   126  	GetAcceptedFrontierF, GetFailedF, GetAncestorsFailedF,
   127  	QueryFailedF, GetAcceptedFrontierFailedF, GetAcceptedFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error
   128  	AppRequestFailedF           func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error
   129  	StateSummaryFrontierF       func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summary []byte) error
   130  	GetAcceptedStateSummaryF    func(ctx context.Context, nodeID ids.NodeID, requestID uint32, keys set.Set[uint64]) error
   131  	AcceptedStateSummaryF       func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error
   132  	ConnectedF                  func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error
   133  	DisconnectedF               func(ctx context.Context, nodeID ids.NodeID) error
   134  	HealthF                     func(context.Context) (interface{}, error)
   135  	GetVMF                      func() VM
   136  	AppRequestF                 func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error
   137  	AppResponseF                func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error
   138  	AppGossipF                  func(ctx context.Context, nodeID ids.NodeID, msg []byte) error
   139  	CrossChainAppRequestF       func(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, msg []byte) error
   140  	CrossChainAppResponseF      func(ctx context.Context, chainID ids.ID, requestID uint32, msg []byte) error
   141  	CrossChainAppRequestFailedF func(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error
   142  }
   143  
   144  func (e *EngineTest) Default(cant bool) {
   145  	e.CantStart = cant
   146  	e.CantIsBootstrapped = cant
   147  	e.CantTimeout = cant
   148  	e.CantGossip = cant
   149  	e.CantHalt = cant
   150  	e.CantShutdown = cant
   151  	e.CantContext = cant
   152  	e.CantNotify = cant
   153  	e.CantGetStateSummaryFrontier = cant
   154  	e.CantGetStateSummaryFrontierFailed = cant
   155  	e.CantStateSummaryFrontier = cant
   156  	e.CantGetAcceptedStateSummary = cant
   157  	e.CantGetAcceptedStateSummaryFailed = cant
   158  	e.CantAcceptedStateSummary = cant
   159  	e.CantGetAcceptedFrontier = cant
   160  	e.CantGetAcceptedFrontierFailed = cant
   161  	e.CantAcceptedFrontier = cant
   162  	e.CantGetAccepted = cant
   163  	e.CantGetAcceptedFailed = cant
   164  	e.CantAccepted = cant
   165  	e.CantGet = cant
   166  	e.CantGetAncestors = cant
   167  	e.CantGetAncestorsFailed = cant
   168  	e.CantGetFailed = cant
   169  	e.CantPut = cant
   170  	e.CantAncestors = cant
   171  	e.CantPushQuery = cant
   172  	e.CantPullQuery = cant
   173  	e.CantQueryFailed = cant
   174  	e.CantChits = cant
   175  	e.CantConnected = cant
   176  	e.CantDisconnected = cant
   177  	e.CantHealth = cant
   178  	e.CantAppRequest = cant
   179  	e.CantAppRequestFailed = cant
   180  	e.CantAppResponse = cant
   181  	e.CantAppGossip = cant
   182  	e.CantGetVM = cant
   183  	e.CantCrossChainAppRequest = cant
   184  	e.CantCrossChainAppRequestFailed = cant
   185  	e.CantCrossChainAppResponse = cant
   186  }
   187  
   188  func (e *EngineTest) Start(ctx context.Context, startReqID uint32) error {
   189  	if e.StartF != nil {
   190  		return e.StartF(ctx, startReqID)
   191  	}
   192  	if !e.CantStart {
   193  		return nil
   194  	}
   195  	if e.T != nil {
   196  		require.FailNow(e.T, errStart.Error())
   197  	}
   198  	return errStart
   199  }
   200  
   201  func (e *EngineTest) Context() *snow.ConsensusContext {
   202  	if e.ContextF != nil {
   203  		return e.ContextF()
   204  	}
   205  	if !e.CantContext {
   206  		return nil
   207  	}
   208  	if e.T != nil {
   209  		require.FailNow(e.T, "Unexpectedly called Context")
   210  	}
   211  	return nil
   212  }
   213  
   214  func (e *EngineTest) Timeout(ctx context.Context) error {
   215  	if e.TimeoutF != nil {
   216  		return e.TimeoutF(ctx)
   217  	}
   218  	if !e.CantTimeout {
   219  		return nil
   220  	}
   221  	if e.T != nil {
   222  		require.FailNow(e.T, errTimeout.Error())
   223  	}
   224  	return errTimeout
   225  }
   226  
   227  func (e *EngineTest) Gossip(ctx context.Context) error {
   228  	if e.GossipF != nil {
   229  		return e.GossipF(ctx)
   230  	}
   231  	if !e.CantGossip {
   232  		return nil
   233  	}
   234  	if e.T != nil {
   235  		require.FailNow(e.T, errGossip.Error())
   236  	}
   237  	return errGossip
   238  }
   239  
   240  func (e *EngineTest) Halt(ctx context.Context) {
   241  	if e.HaltF != nil {
   242  		e.HaltF(ctx)
   243  		return
   244  	}
   245  	if !e.CantHalt {
   246  		return
   247  	}
   248  	if e.T != nil {
   249  		require.FailNow(e.T, "Unexpectedly called Halt")
   250  	}
   251  }
   252  
   253  func (e *EngineTest) Shutdown(ctx context.Context) error {
   254  	if e.ShutdownF != nil {
   255  		return e.ShutdownF(ctx)
   256  	}
   257  	if !e.CantShutdown {
   258  		return nil
   259  	}
   260  	if e.T != nil {
   261  		require.FailNow(e.T, errShutdown.Error())
   262  	}
   263  	return errShutdown
   264  }
   265  
   266  func (e *EngineTest) Notify(ctx context.Context, msg Message) error {
   267  	if e.NotifyF != nil {
   268  		return e.NotifyF(ctx, msg)
   269  	}
   270  	if !e.CantNotify {
   271  		return nil
   272  	}
   273  	if e.T != nil {
   274  		require.FailNow(e.T, errNotify.Error())
   275  	}
   276  	return errNotify
   277  }
   278  
   279  func (e *EngineTest) GetStateSummaryFrontier(ctx context.Context, validatorID ids.NodeID, requestID uint32) error {
   280  	if e.GetStateSummaryFrontierF != nil {
   281  		return e.GetStateSummaryFrontierF(ctx, validatorID, requestID)
   282  	}
   283  	if !e.CantGetStateSummaryFrontier {
   284  		return nil
   285  	}
   286  	if e.T != nil {
   287  		require.FailNow(e.T, errGetStateSummaryFrontier.Error())
   288  	}
   289  	return errGetStateSummaryFrontier
   290  }
   291  
   292  func (e *EngineTest) StateSummaryFrontier(ctx context.Context, validatorID ids.NodeID, requestID uint32, summary []byte) error {
   293  	if e.StateSummaryFrontierF != nil {
   294  		return e.StateSummaryFrontierF(ctx, validatorID, requestID, summary)
   295  	}
   296  	if !e.CantStateSummaryFrontier {
   297  		return nil
   298  	}
   299  	if e.T != nil {
   300  		require.FailNow(e.T, errStateSummaryFrontier.Error())
   301  	}
   302  	return errStateSummaryFrontier
   303  }
   304  
   305  func (e *EngineTest) GetStateSummaryFrontierFailed(ctx context.Context, validatorID ids.NodeID, requestID uint32) error {
   306  	if e.GetStateSummaryFrontierFailedF != nil {
   307  		return e.GetStateSummaryFrontierFailedF(ctx, validatorID, requestID)
   308  	}
   309  	if !e.CantGetStateSummaryFrontierFailed {
   310  		return nil
   311  	}
   312  	if e.T != nil {
   313  		require.FailNow(e.T, errGetStateSummaryFrontierFailed.Error())
   314  	}
   315  	return errGetStateSummaryFrontierFailed
   316  }
   317  
   318  func (e *EngineTest) GetAcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, keys set.Set[uint64]) error {
   319  	if e.GetAcceptedStateSummaryF != nil {
   320  		return e.GetAcceptedStateSummaryF(ctx, validatorID, requestID, keys)
   321  	}
   322  	if !e.CantGetAcceptedStateSummary {
   323  		return nil
   324  	}
   325  	if e.T != nil {
   326  		require.FailNow(e.T, errGetAcceptedStateSummary.Error())
   327  	}
   328  	return errGetAcceptedStateSummary
   329  }
   330  
   331  func (e *EngineTest) AcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error {
   332  	if e.AcceptedStateSummaryF != nil {
   333  		return e.AcceptedStateSummaryF(ctx, validatorID, requestID, summaryIDs)
   334  	}
   335  	if !e.CantAcceptedStateSummary {
   336  		return nil
   337  	}
   338  	if e.T != nil {
   339  		require.FailNow(e.T, errAcceptedStateSummary.Error())
   340  	}
   341  	return errAcceptedStateSummary
   342  }
   343  
   344  func (e *EngineTest) GetAcceptedStateSummaryFailed(ctx context.Context, validatorID ids.NodeID, requestID uint32) error {
   345  	if e.GetAcceptedStateSummaryFailedF != nil {
   346  		return e.GetAcceptedStateSummaryFailedF(ctx, validatorID, requestID)
   347  	}
   348  	if !e.CantGetAcceptedStateSummaryFailed {
   349  		return nil
   350  	}
   351  	if e.T != nil {
   352  		require.FailNow(e.T, errGetAcceptedStateSummaryFailed.Error())
   353  	}
   354  	return errGetAcceptedStateSummaryFailed
   355  }
   356  
   357  func (e *EngineTest) GetAcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   358  	if e.GetAcceptedFrontierF != nil {
   359  		return e.GetAcceptedFrontierF(ctx, nodeID, requestID)
   360  	}
   361  	if !e.CantGetAcceptedFrontier {
   362  		return nil
   363  	}
   364  	if e.T != nil {
   365  		require.FailNow(e.T, errGetAcceptedFrontier.Error())
   366  	}
   367  	return errGetAcceptedFrontier
   368  }
   369  
   370  func (e *EngineTest) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   371  	if e.GetAcceptedFrontierFailedF != nil {
   372  		return e.GetAcceptedFrontierFailedF(ctx, nodeID, requestID)
   373  	}
   374  	if !e.CantGetAcceptedFrontierFailed {
   375  		return nil
   376  	}
   377  	if e.T != nil {
   378  		require.FailNow(e.T, errGetAcceptedFrontierFailed.Error())
   379  	}
   380  	return errGetAcceptedFrontierFailed
   381  }
   382  
   383  func (e *EngineTest) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error {
   384  	if e.AcceptedFrontierF != nil {
   385  		return e.AcceptedFrontierF(ctx, nodeID, requestID, containerID)
   386  	}
   387  	if !e.CantAcceptedFrontier {
   388  		return nil
   389  	}
   390  	if e.T != nil {
   391  		require.FailNow(e.T, errAcceptedFrontier.Error())
   392  	}
   393  	return errAcceptedFrontier
   394  }
   395  
   396  func (e *EngineTest) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error {
   397  	if e.GetAcceptedF != nil {
   398  		return e.GetAcceptedF(ctx, nodeID, requestID, containerIDs)
   399  	}
   400  	if !e.CantGetAccepted {
   401  		return nil
   402  	}
   403  	if e.T != nil {
   404  		require.FailNow(e.T, errGetAccepted.Error())
   405  	}
   406  	return errGetAccepted
   407  }
   408  
   409  func (e *EngineTest) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   410  	if e.GetAcceptedFailedF != nil {
   411  		return e.GetAcceptedFailedF(ctx, nodeID, requestID)
   412  	}
   413  	if !e.CantGetAcceptedFailed {
   414  		return nil
   415  	}
   416  	if e.T != nil {
   417  		require.FailNow(e.T, errGetAcceptedFailed.Error())
   418  	}
   419  	return errGetAcceptedFailed
   420  }
   421  
   422  func (e *EngineTest) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error {
   423  	if e.AcceptedF != nil {
   424  		return e.AcceptedF(ctx, nodeID, requestID, containerIDs)
   425  	}
   426  	if !e.CantAccepted {
   427  		return nil
   428  	}
   429  	if e.T != nil {
   430  		require.FailNow(e.T, errAccepted.Error())
   431  	}
   432  	return errAccepted
   433  }
   434  
   435  func (e *EngineTest) Get(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error {
   436  	if e.GetF != nil {
   437  		return e.GetF(ctx, nodeID, requestID, containerID)
   438  	}
   439  	if !e.CantGet {
   440  		return nil
   441  	}
   442  	if e.T != nil {
   443  		require.FailNow(e.T, errGet.Error())
   444  	}
   445  	return errGet
   446  }
   447  
   448  func (e *EngineTest) GetAncestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error {
   449  	if e.GetAncestorsF != nil {
   450  		return e.GetAncestorsF(ctx, nodeID, requestID, containerID)
   451  	}
   452  	if !e.CantGetAncestors {
   453  		return nil
   454  	}
   455  	if e.T != nil {
   456  		require.FailNow(e.T, errGetAncestors.Error())
   457  	}
   458  	return errGetAncestors
   459  }
   460  
   461  func (e *EngineTest) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   462  	if e.GetFailedF != nil {
   463  		return e.GetFailedF(ctx, nodeID, requestID)
   464  	}
   465  	if !e.CantGetFailed {
   466  		return nil
   467  	}
   468  	if e.T != nil {
   469  		require.FailNow(e.T, errGetFailed.Error())
   470  	}
   471  	return errGetFailed
   472  }
   473  
   474  func (e *EngineTest) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   475  	if e.GetAncestorsFailedF != nil {
   476  		return e.GetAncestorsFailedF(ctx, nodeID, requestID)
   477  	}
   478  	if !e.CantGetAncestorsFailed {
   479  		return nil
   480  	}
   481  	if e.T != nil {
   482  		require.FailNow(e.T, errGetAncestorsFailed.Error())
   483  	}
   484  	return errGetAncestorsFailed
   485  }
   486  
   487  func (e *EngineTest) Put(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte) error {
   488  	if e.PutF != nil {
   489  		return e.PutF(ctx, nodeID, requestID, container)
   490  	}
   491  	if !e.CantPut {
   492  		return nil
   493  	}
   494  	if e.T != nil {
   495  		require.FailNow(e.T, errPut.Error())
   496  	}
   497  	return errPut
   498  }
   499  
   500  func (e *EngineTest) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, containers [][]byte) error {
   501  	if e.AncestorsF != nil {
   502  		return e.AncestorsF(ctx, nodeID, requestID, containers)
   503  	}
   504  	if !e.CantAncestors {
   505  		return nil
   506  	}
   507  	if e.T != nil {
   508  		require.FailNow(e.T, errAncestors.Error())
   509  	}
   510  	return errAncestors
   511  }
   512  
   513  func (e *EngineTest) PushQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte, requestedHeight uint64) error {
   514  	if e.PushQueryF != nil {
   515  		return e.PushQueryF(ctx, nodeID, requestID, container, requestedHeight)
   516  	}
   517  	if !e.CantPushQuery {
   518  		return nil
   519  	}
   520  	if e.T != nil {
   521  		require.FailNow(e.T, errPushQuery.Error())
   522  	}
   523  	return errPushQuery
   524  }
   525  
   526  func (e *EngineTest) PullQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID, requestedHeight uint64) error {
   527  	if e.PullQueryF != nil {
   528  		return e.PullQueryF(ctx, nodeID, requestID, containerID, requestedHeight)
   529  	}
   530  	if !e.CantPullQuery {
   531  		return nil
   532  	}
   533  	if e.T != nil {
   534  		require.FailNow(e.T, errPullQuery.Error())
   535  	}
   536  	return errPullQuery
   537  }
   538  
   539  func (e *EngineTest) QueryFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error {
   540  	if e.QueryFailedF != nil {
   541  		return e.QueryFailedF(ctx, nodeID, requestID)
   542  	}
   543  	if !e.CantQueryFailed {
   544  		return nil
   545  	}
   546  	if e.T != nil {
   547  		require.FailNow(e.T, errQueryFailed.Error())
   548  	}
   549  	return errQueryFailed
   550  }
   551  
   552  func (e *EngineTest) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error {
   553  	if e.CrossChainAppRequestF != nil {
   554  		return e.CrossChainAppRequestF(ctx, chainID, requestID, deadline, request)
   555  	}
   556  	if !e.CantCrossChainAppRequest {
   557  		return nil
   558  	}
   559  	if e.T != nil {
   560  		require.FailNow(e.T, errCrossChainAppRequest.Error())
   561  	}
   562  	return errCrossChainAppRequest
   563  }
   564  
   565  func (e *EngineTest) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error {
   566  	if e.CrossChainAppRequestFailedF != nil {
   567  		return e.CrossChainAppRequestFailedF(ctx, chainID, requestID, appErr)
   568  	}
   569  	if !e.CantCrossChainAppRequestFailed {
   570  		return nil
   571  	}
   572  	if e.T != nil {
   573  		require.FailNow(e.T, errCrossChainAppRequestFailed.Error())
   574  	}
   575  	return errCrossChainAppRequestFailed
   576  }
   577  
   578  func (e *EngineTest) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error {
   579  	if e.CrossChainAppResponseF != nil {
   580  		return e.CrossChainAppResponseF(ctx, chainID, requestID, response)
   581  	}
   582  	if !e.CantCrossChainAppResponse {
   583  		return nil
   584  	}
   585  	if e.T != nil {
   586  		require.FailNow(e.T, errCrossChainAppResponse.Error())
   587  	}
   588  	return errCrossChainAppResponse
   589  }
   590  
   591  func (e *EngineTest) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error {
   592  	if e.AppRequestF != nil {
   593  		return e.AppRequestF(ctx, nodeID, requestID, deadline, request)
   594  	}
   595  	if !e.CantAppRequest {
   596  		return nil
   597  	}
   598  	if e.T != nil {
   599  		require.FailNow(e.T, errAppRequest.Error())
   600  	}
   601  	return errAppRequest
   602  }
   603  
   604  func (e *EngineTest) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error {
   605  	if e.AppResponseF != nil {
   606  		return e.AppResponseF(ctx, nodeID, requestID, response)
   607  	}
   608  	if !e.CantAppResponse {
   609  		return nil
   610  	}
   611  	if e.T != nil {
   612  		require.FailNow(e.T, errAppResponse.Error())
   613  	}
   614  	return errAppResponse
   615  }
   616  
   617  func (e *EngineTest) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error {
   618  	if e.AppRequestFailedF != nil {
   619  		return e.AppRequestFailedF(ctx, nodeID, requestID, appErr)
   620  	}
   621  	if !e.CantAppRequestFailed {
   622  		return nil
   623  	}
   624  	if e.T != nil {
   625  		require.FailNow(e.T, errAppRequestFailed.Error())
   626  	}
   627  	return errAppRequestFailed
   628  }
   629  
   630  func (e *EngineTest) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error {
   631  	if e.AppGossipF != nil {
   632  		return e.AppGossipF(ctx, nodeID, msg)
   633  	}
   634  	if !e.CantAppGossip {
   635  		return nil
   636  	}
   637  	if e.T != nil {
   638  		require.FailNow(e.T, errAppGossip.Error())
   639  	}
   640  	return errAppGossip
   641  }
   642  
   643  func (e *EngineTest) Chits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error {
   644  	if e.ChitsF != nil {
   645  		return e.ChitsF(ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID)
   646  	}
   647  	if !e.CantChits {
   648  		return nil
   649  	}
   650  	if e.T != nil {
   651  		require.FailNow(e.T, errChits.Error())
   652  	}
   653  	return errChits
   654  }
   655  
   656  func (e *EngineTest) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error {
   657  	if e.ConnectedF != nil {
   658  		return e.ConnectedF(ctx, nodeID, nodeVersion)
   659  	}
   660  	if !e.CantConnected {
   661  		return nil
   662  	}
   663  	if e.T != nil {
   664  		require.FailNow(e.T, errConnected.Error())
   665  	}
   666  	return errConnected
   667  }
   668  
   669  func (e *EngineTest) Disconnected(ctx context.Context, nodeID ids.NodeID) error {
   670  	if e.DisconnectedF != nil {
   671  		return e.DisconnectedF(ctx, nodeID)
   672  	}
   673  	if !e.CantDisconnected {
   674  		return nil
   675  	}
   676  	if e.T != nil {
   677  		require.FailNow(e.T, errDisconnected.Error())
   678  	}
   679  	return errDisconnected
   680  }
   681  
   682  func (e *EngineTest) HealthCheck(ctx context.Context) (interface{}, error) {
   683  	if e.HealthF != nil {
   684  		return e.HealthF(ctx)
   685  	}
   686  	if !e.CantHealth {
   687  		return nil, nil
   688  	}
   689  	if e.T != nil {
   690  		require.FailNow(e.T, errHealthCheck.Error())
   691  	}
   692  	return nil, errHealthCheck
   693  }