github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/protocol/api_test.go (about)

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/suite"
     8  
     9  	protocol "github.com/onflow/flow-go/state/protocol/mock"
    10  	"github.com/onflow/flow-go/storage"
    11  	storagemock "github.com/onflow/flow-go/storage/mock"
    12  	"github.com/onflow/flow-go/utils/unittest"
    13  
    14  	"google.golang.org/grpc/codes"
    15  	"google.golang.org/grpc/status"
    16  )
    17  
    18  var CodesNotFoundErr = status.Errorf(codes.NotFound, "not found")
    19  var StorageNotFoundErr = status.Errorf(codes.NotFound, "not found: %v", storage.ErrNotFound)
    20  var InternalErr = status.Errorf(codes.Internal, "internal")
    21  var OutputInternalErr = status.Errorf(codes.Internal, "failed to find: %v", status.Errorf(codes.Internal, "internal"))
    22  
    23  type Suite struct {
    24  	suite.Suite
    25  
    26  	state            *protocol.State
    27  	blocks           *storagemock.Blocks
    28  	headers          *storagemock.Headers
    29  	executionResults *storagemock.ExecutionResults
    30  	snapshot         *protocol.Snapshot
    31  }
    32  
    33  func TestHandler(t *testing.T) {
    34  	suite.Run(t, new(Suite))
    35  }
    36  
    37  func (suite *Suite) SetupTest() {
    38  	suite.snapshot = new(protocol.Snapshot)
    39  
    40  	suite.state = new(protocol.State)
    41  	suite.blocks = new(storagemock.Blocks)
    42  	suite.headers = new(storagemock.Headers)
    43  	suite.executionResults = new(storagemock.ExecutionResults)
    44  }
    45  
    46  func (suite *Suite) TestGetLatestFinalizedBlock_Success() {
    47  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
    48  
    49  	// setup the mocks
    50  	block := unittest.BlockFixture()
    51  	header := block.Header
    52  
    53  	suite.snapshot.
    54  		On("Head").
    55  		Return(header, nil).
    56  		Once()
    57  
    58  	suite.blocks.
    59  		On("ByID", header.ID()).
    60  		Return(&block, nil).
    61  		Once()
    62  
    63  	backend := New(suite.state, suite.blocks, suite.headers, nil)
    64  
    65  	// query the handler for the latest finalized block
    66  	responseBlock, err := backend.GetLatestBlock(context.Background(), false)
    67  	suite.checkResponse(responseBlock, err)
    68  
    69  	// make sure we got the latest block
    70  	suite.Require().Equal(block, *responseBlock)
    71  
    72  	suite.assertAllExpectations()
    73  }
    74  
    75  func (suite *Suite) TestGetLatestSealedBlock_Success() {
    76  	suite.state.On("Sealed").Return(suite.snapshot, nil).Maybe()
    77  
    78  	// setup the mocks
    79  	block := unittest.BlockFixture()
    80  	header := block.Header
    81  
    82  	suite.snapshot.
    83  		On("Head").
    84  		Return(header, nil).
    85  		Once()
    86  
    87  	suite.blocks.
    88  		On("ByID", header.ID()).
    89  		Return(&block, nil).
    90  		Once()
    91  
    92  	backend := New(suite.state, suite.blocks, suite.headers, nil)
    93  
    94  	// query the handler for the latest finalized block
    95  	responseBlock, err := backend.GetLatestBlock(context.Background(), true)
    96  	suite.checkResponse(responseBlock, err)
    97  
    98  	// make sure we got the latest block
    99  	suite.Require().Equal(block, *responseBlock)
   100  
   101  	suite.assertAllExpectations()
   102  }
   103  
   104  func (suite *Suite) TestGetLatestBlock_StorageNotFoundFailure() {
   105  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   106  
   107  	// setup the mocks
   108  	block := unittest.BlockFixture()
   109  	header := block.Header
   110  
   111  	suite.snapshot.
   112  		On("Head").
   113  		Return(header, storage.ErrNotFound).
   114  		Once()
   115  
   116  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   117  
   118  	// query the handler for the latest finalized block
   119  	_, err := backend.GetLatestBlock(context.Background(), false)
   120  	suite.Require().Error(err)
   121  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   122  
   123  	suite.assertAllExpectations()
   124  }
   125  
   126  func (suite *Suite) TestGetLatestBlock_CodesNotFoundFailure() {
   127  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   128  
   129  	// setup the mocks
   130  	block := unittest.BlockFixture()
   131  	header := block.Header
   132  
   133  	suite.snapshot.
   134  		On("Head").
   135  		Return(header, CodesNotFoundErr).
   136  		Once()
   137  
   138  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   139  
   140  	// query the handler for the latest finalized block
   141  	_, err := backend.GetLatestBlock(context.Background(), false)
   142  	suite.Require().Error(err)
   143  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   144  
   145  	suite.assertAllExpectations()
   146  }
   147  
   148  func (suite *Suite) TestGetLatestBlock_InternalFailure() {
   149  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   150  
   151  	// setup the mocks
   152  	block := unittest.BlockFixture()
   153  	header := block.Header
   154  
   155  	suite.snapshot.
   156  		On("Head").
   157  		Return(header, InternalErr).
   158  		Once()
   159  
   160  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   161  
   162  	// query the handler for the latest finalized block
   163  	_, err := backend.GetLatestBlock(context.Background(), false)
   164  	suite.Require().Error(err)
   165  	suite.Require().ErrorIs(err, OutputInternalErr)
   166  
   167  	suite.assertAllExpectations()
   168  }
   169  
   170  func (suite *Suite) TestGetBlockById_Success() {
   171  	// setup the mocks
   172  	block := unittest.BlockFixture()
   173  
   174  	suite.blocks.
   175  		On("ByID", block.ID()).
   176  		Return(&block, nil).
   177  		Once()
   178  
   179  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   180  
   181  	// query the handler for the latest sealed block
   182  	responseBlock, err := backend.GetBlockByID(context.Background(), block.ID())
   183  	suite.checkResponse(responseBlock, err)
   184  
   185  	// make sure we got the latest block
   186  	suite.Require().Equal(block.ID(), responseBlock.ID())
   187  
   188  	suite.assertAllExpectations()
   189  }
   190  
   191  func (suite *Suite) TestGetBlockById_StorageNotFoundFailure() {
   192  	// setup the mocks
   193  	block := unittest.BlockFixture()
   194  
   195  	suite.blocks.
   196  		On("ByID", block.ID()).
   197  		Return(&block, storage.ErrNotFound).
   198  		Once()
   199  
   200  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   201  
   202  	// query the handler for the latest block
   203  	_, err := backend.GetBlockByID(context.Background(), block.ID())
   204  	suite.Require().Error(err)
   205  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   206  
   207  	suite.assertAllExpectations()
   208  }
   209  
   210  func (suite *Suite) TestGetBlockById_CodesNotFoundFailure() {
   211  	// setup the mocks
   212  	block := unittest.BlockFixture()
   213  
   214  	suite.blocks.
   215  		On("ByID", block.ID()).
   216  		Return(&block, CodesNotFoundErr).
   217  		Once()
   218  
   219  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   220  
   221  	// query the handler for the latest block
   222  	_, err := backend.GetBlockByID(context.Background(), block.ID())
   223  	suite.Require().Error(err)
   224  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   225  
   226  	suite.assertAllExpectations()
   227  }
   228  
   229  func (suite *Suite) TestGetBlockById_InternalFailure() {
   230  	// setup the mocks
   231  	block := unittest.BlockFixture()
   232  
   233  	suite.blocks.
   234  		On("ByID", block.ID()).
   235  		Return(&block, InternalErr).
   236  		Once()
   237  
   238  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   239  
   240  	// query the handler for the latest block
   241  	_, err := backend.GetBlockByID(context.Background(), block.ID())
   242  	suite.Require().Error(err)
   243  	suite.Require().ErrorIs(err, OutputInternalErr)
   244  
   245  	suite.assertAllExpectations()
   246  }
   247  
   248  func (suite *Suite) TestGetBlockByHeight_Success() {
   249  	// setup the mocks
   250  	block := unittest.BlockFixture()
   251  	height := block.Header.Height
   252  
   253  	suite.blocks.
   254  		On("ByHeight", height).
   255  		Return(&block, nil).
   256  		Once()
   257  
   258  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   259  
   260  	// query the handler for the latest block
   261  	responseBlock, err := backend.GetBlockByHeight(context.Background(), height)
   262  	suite.checkResponse(responseBlock, err)
   263  
   264  	// make sure we got the latest block
   265  	suite.Require().Equal(block.ID(), responseBlock.ID())
   266  
   267  	suite.assertAllExpectations()
   268  }
   269  
   270  func (suite *Suite) TestGetBlockByHeight_StorageNotFoundFailure() {
   271  	// setup the mocks
   272  	block := unittest.BlockFixture()
   273  	height := block.Header.Height
   274  
   275  	suite.blocks.
   276  		On("ByHeight", height).
   277  		Return(&block, StorageNotFoundErr).
   278  		Once()
   279  
   280  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   281  
   282  	// query the handler for the latest block
   283  	_, err := backend.GetBlockByHeight(context.Background(), height)
   284  	suite.Require().Error(err)
   285  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   286  
   287  	suite.assertAllExpectations()
   288  }
   289  
   290  func (suite *Suite) TestGetBlockByHeight_CodesNotFoundFailure() {
   291  	// setup the mocks
   292  	block := unittest.BlockFixture()
   293  	height := block.Header.Height
   294  
   295  	suite.blocks.
   296  		On("ByHeight", height).
   297  		Return(&block, CodesNotFoundErr).
   298  		Once()
   299  
   300  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   301  
   302  	// query the handler for the latest block
   303  	_, err := backend.GetBlockByHeight(context.Background(), height)
   304  	suite.Require().Error(err)
   305  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   306  
   307  	suite.assertAllExpectations()
   308  }
   309  
   310  func (suite *Suite) TestGetBlockByHeight_InternalFailure() {
   311  	// setup the mocks
   312  	block := unittest.BlockFixture()
   313  	height := block.Header.Height
   314  
   315  	suite.blocks.
   316  		On("ByHeight", height).
   317  		Return(&block, InternalErr).
   318  		Once()
   319  
   320  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   321  
   322  	// query the handler for the latest block
   323  	_, err := backend.GetBlockByHeight(context.Background(), height)
   324  	suite.Require().Error(err)
   325  	suite.Require().ErrorIs(err, OutputInternalErr)
   326  
   327  	suite.assertAllExpectations()
   328  }
   329  
   330  func (suite *Suite) TestGetLatestFinalizedBlockHeader_Success() {
   331  	// setup the mocks
   332  	blockHeader := unittest.BlockHeaderFixture()
   333  
   334  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   335  	suite.snapshot.On("Head").Return(blockHeader, nil).Once()
   336  
   337  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   338  
   339  	// query the handler for the latest finalized block
   340  	responseBlockHeader, err := backend.GetLatestBlockHeader(context.Background(), false)
   341  	suite.checkResponse(responseBlockHeader, err)
   342  
   343  	// make sure we got the latest finalized block
   344  	suite.Require().Equal(blockHeader.ID(), responseBlockHeader.ID())
   345  	suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height)
   346  	suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID)
   347  
   348  	suite.assertAllExpectations()
   349  }
   350  
   351  func (suite *Suite) TestGetLatestSealedBlockHeader_Success() {
   352  	// setup the mocks
   353  	blockHeader := unittest.BlockHeaderFixture()
   354  
   355  	suite.state.On("Sealed").Return(suite.snapshot, nil).Maybe()
   356  	suite.snapshot.On("Head").Return(blockHeader, nil).Once()
   357  
   358  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   359  
   360  	// query the handler for the latest sealed block
   361  	responseBlockHeader, err := backend.GetLatestBlockHeader(context.Background(), true)
   362  	suite.checkResponse(responseBlockHeader, err)
   363  
   364  	// make sure we got the latest sealed block
   365  	suite.Require().Equal(blockHeader.ID(), responseBlockHeader.ID())
   366  	suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height)
   367  	suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID)
   368  
   369  	suite.assertAllExpectations()
   370  }
   371  
   372  func (suite *Suite) TestGetLatestBlockHeader_StorageNotFoundFailure() {
   373  	// setup the mocks
   374  	blockHeader := unittest.BlockHeaderFixture()
   375  
   376  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   377  	suite.snapshot.On("Head").Return(blockHeader, storage.ErrNotFound).Once()
   378  
   379  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   380  
   381  	// query the handler for the latest block
   382  	_, err := backend.GetLatestBlockHeader(context.Background(), false)
   383  	suite.Require().Error(err)
   384  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   385  
   386  	suite.assertAllExpectations()
   387  }
   388  
   389  func (suite *Suite) TestGetLatestBlockHeader_CodesNotFoundFailure() {
   390  	// setup the mocks
   391  	blockHeader := unittest.BlockHeaderFixture()
   392  
   393  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   394  	suite.snapshot.On("Head").Return(blockHeader, CodesNotFoundErr).Once()
   395  
   396  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   397  
   398  	// query the handler for the latest block
   399  	_, err := backend.GetLatestBlockHeader(context.Background(), false)
   400  	suite.Require().Error(err)
   401  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   402  
   403  	suite.assertAllExpectations()
   404  }
   405  
   406  func (suite *Suite) TestGetLatestBlockHeader_InternalFailure() {
   407  	// setup the mocks
   408  	blockHeader := unittest.BlockHeaderFixture()
   409  
   410  	suite.state.On("Final").Return(suite.snapshot, nil).Maybe()
   411  	suite.snapshot.On("Head").Return(blockHeader, InternalErr).Once()
   412  
   413  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   414  
   415  	// query the handler for the latest block
   416  	_, err := backend.GetLatestBlockHeader(context.Background(), false)
   417  	suite.Require().Error(err)
   418  	suite.Require().ErrorIs(err, OutputInternalErr)
   419  
   420  	suite.assertAllExpectations()
   421  }
   422  
   423  func (suite *Suite) TestGetBlockHeaderByID_Success() {
   424  	// setup the mocks
   425  	block := unittest.BlockFixture()
   426  	header := block.Header
   427  
   428  	suite.headers.
   429  		On("ByBlockID", block.ID()).
   430  		Return(header, nil).
   431  		Once()
   432  
   433  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   434  
   435  	// query the handler for the latest block
   436  	responseBlockHeader, err := backend.GetBlockHeaderByID(context.Background(), block.ID())
   437  
   438  	suite.checkResponse(responseBlockHeader, err)
   439  
   440  	// make sure we got the latest block
   441  	suite.Require().Equal(header.ID(), responseBlockHeader.ID())
   442  	suite.Require().Equal(header.Height, responseBlockHeader.Height)
   443  	suite.Require().Equal(header.ParentID, responseBlockHeader.ParentID)
   444  
   445  	suite.assertAllExpectations()
   446  }
   447  
   448  func (suite *Suite) TestGetBlockHeaderByID_StorageNotFoundFailure() {
   449  	// setup the mocks
   450  	block := unittest.BlockFixture()
   451  	header := block.Header
   452  
   453  	suite.headers.
   454  		On("ByBlockID", block.ID()).
   455  		Return(header, StorageNotFoundErr).
   456  		Once()
   457  
   458  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   459  
   460  	// query the handler for the block header
   461  	_, err := backend.GetBlockHeaderByID(context.Background(), block.ID())
   462  	suite.Require().Error(err)
   463  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   464  
   465  	suite.assertAllExpectations()
   466  }
   467  
   468  func (suite *Suite) TestGetBlockHeaderByID_CodesNotFoundFailure() {
   469  	// setup the mocks
   470  	block := unittest.BlockFixture()
   471  	header := block.Header
   472  
   473  	suite.headers.
   474  		On("ByBlockID", block.ID()).
   475  		Return(header, CodesNotFoundErr).
   476  		Once()
   477  
   478  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   479  
   480  	// query the handler for the block header
   481  	_, err := backend.GetBlockHeaderByID(context.Background(), block.ID())
   482  	suite.Require().Error(err)
   483  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   484  
   485  	suite.assertAllExpectations()
   486  }
   487  
   488  func (suite *Suite) TestGetBlockHeaderByID_InternalFailure() {
   489  	// setup the mocks
   490  	block := unittest.BlockFixture()
   491  	header := block.Header
   492  
   493  	suite.headers.
   494  		On("ByBlockID", block.ID()).
   495  		Return(header, InternalErr).
   496  		Once()
   497  
   498  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   499  
   500  	// query the handler for the block header
   501  	_, err := backend.GetBlockHeaderByID(context.Background(), block.ID())
   502  	suite.Require().Error(err)
   503  	suite.Require().ErrorIs(err, OutputInternalErr)
   504  
   505  	suite.assertAllExpectations()
   506  }
   507  
   508  func (suite *Suite) TestGetBlockHeaderByHeight_Success() {
   509  	// setup the mocks
   510  	blockHeader := unittest.BlockHeaderFixture()
   511  	headerHeight := blockHeader.Height
   512  
   513  	suite.headers.
   514  		On("ByHeight", headerHeight).
   515  		Return(blockHeader, nil).
   516  		Once()
   517  
   518  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   519  
   520  	// query the handler for the block header
   521  	responseBlockHeader, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight)
   522  
   523  	suite.checkResponse(responseBlockHeader, err)
   524  
   525  	// make sure we got the block header
   526  	suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height)
   527  	suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID)
   528  
   529  	suite.assertAllExpectations()
   530  }
   531  
   532  func (suite *Suite) TestGetBlockHeaderByHeight_StorageNotFoundFailure() {
   533  	// setup the mocks
   534  	blockHeader := unittest.BlockHeaderFixture()
   535  	headerHeight := blockHeader.Height
   536  
   537  	suite.headers.
   538  		On("ByHeight", headerHeight).
   539  		Return(blockHeader, StorageNotFoundErr).
   540  		Once()
   541  
   542  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   543  
   544  	// query the handler for the block header
   545  	_, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight)
   546  	suite.Require().Error(err)
   547  	suite.Require().ErrorIs(err, StorageNotFoundErr)
   548  
   549  	suite.assertAllExpectations()
   550  }
   551  
   552  func (suite *Suite) TestGetBlockHeaderByHeight_CodesNotFoundFailure() {
   553  	// setup the mocks
   554  	blockHeader := unittest.BlockHeaderFixture()
   555  	headerHeight := blockHeader.Height
   556  
   557  	suite.headers.
   558  		On("ByHeight", headerHeight).
   559  		Return(blockHeader, CodesNotFoundErr).
   560  		Once()
   561  
   562  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   563  
   564  	// query the handler for the block header
   565  	_, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight)
   566  	suite.Require().Error(err)
   567  	suite.Require().ErrorIs(err, CodesNotFoundErr)
   568  
   569  	suite.assertAllExpectations()
   570  }
   571  
   572  func (suite *Suite) TestGetBlockHeaderByHeight_InternalFailure() {
   573  	// setup the mocks
   574  	blockHeader := unittest.BlockHeaderFixture()
   575  	headerHeight := blockHeader.Height
   576  
   577  	suite.headers.
   578  		On("ByHeight", headerHeight).
   579  		Return(blockHeader, InternalErr).
   580  		Once()
   581  
   582  	backend := New(suite.state, suite.blocks, suite.headers, nil)
   583  
   584  	// query the handler for the block header
   585  	_, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight)
   586  	suite.Require().Error(err)
   587  	suite.Require().ErrorIs(err, OutputInternalErr)
   588  
   589  	suite.assertAllExpectations()
   590  }
   591  
   592  func (suite *Suite) checkResponse(resp interface{}, err error) {
   593  	suite.Require().NoError(err)
   594  	suite.Require().NotNil(resp)
   595  }
   596  
   597  func (suite *Suite) assertAllExpectations() {
   598  	suite.snapshot.AssertExpectations(suite.T())
   599  	suite.state.AssertExpectations(suite.T())
   600  	suite.blocks.AssertExpectations(suite.T())
   601  	suite.headers.AssertExpectations(suite.T())
   602  	suite.executionResults.AssertExpectations(suite.T())
   603  }