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

     1  package util
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/dgraph-io/badger/v2"
     7  	"github.com/rs/zerolog"
     8  	"github.com/stretchr/testify/mock"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/onflow/flow-go/model/flow"
    12  	"github.com/onflow/flow-go/module"
    13  	"github.com/onflow/flow-go/module/metrics"
    14  	modulemock "github.com/onflow/flow-go/module/mock"
    15  	"github.com/onflow/flow-go/module/trace"
    16  	"github.com/onflow/flow-go/state/protocol"
    17  	pbadger "github.com/onflow/flow-go/state/protocol/badger"
    18  	"github.com/onflow/flow-go/state/protocol/events"
    19  	mockprotocol "github.com/onflow/flow-go/state/protocol/mock"
    20  	protocol_state "github.com/onflow/flow-go/state/protocol/protocol_state/state"
    21  	"github.com/onflow/flow-go/storage"
    22  	"github.com/onflow/flow-go/storage/util"
    23  	"github.com/onflow/flow-go/utils/unittest"
    24  )
    25  
    26  // MockReceiptValidator returns a ReceiptValidator that accepts
    27  // all receipts without performing any
    28  // integrity checks.
    29  func MockReceiptValidator() module.ReceiptValidator {
    30  	validator := &modulemock.ReceiptValidator{}
    31  	validator.On("Validate", mock.Anything).Return(nil)
    32  	validator.On("ValidatePayload", mock.Anything).Return(nil)
    33  	return validator
    34  }
    35  
    36  // MockBlockTimer returns BlockTimer that accepts all timestamps
    37  // without performing any checks.
    38  func MockBlockTimer() protocol.BlockTimer {
    39  	blockTimer := &mockprotocol.BlockTimer{}
    40  	blockTimer.On("Validate", mock.Anything, mock.Anything).Return(nil)
    41  	return blockTimer
    42  }
    43  
    44  // MockSealValidator returns a SealValidator that accepts
    45  // all seals without performing any
    46  // integrity checks, returns first seal in block as valid one
    47  func MockSealValidator(sealsDB storage.Seals) module.SealValidator {
    48  	validator := &modulemock.SealValidator{}
    49  	validator.On("Validate", mock.Anything).Return(
    50  		func(candidate *flow.Block) *flow.Seal {
    51  			if len(candidate.Payload.Seals) > 0 {
    52  				return candidate.Payload.Seals[0]
    53  			}
    54  			last, _ := sealsDB.HighestInFork(candidate.Header.ParentID)
    55  			return last
    56  		},
    57  		func(candidate *flow.Block) error {
    58  			if len(candidate.Payload.Seals) > 0 {
    59  				return nil
    60  			}
    61  			_, err := sealsDB.HighestInFork(candidate.Header.ParentID)
    62  			return err
    63  		}).Maybe()
    64  	return validator
    65  }
    66  
    67  func RunWithBootstrapState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.State)) {
    68  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
    69  		metrics := metrics.NewNoopCollector()
    70  		all := util.StorageLayer(t, db)
    71  		state, err := pbadger.Bootstrap(
    72  			metrics,
    73  			db,
    74  			all.Headers,
    75  			all.Seals,
    76  			all.Results,
    77  			all.Blocks,
    78  			all.QuorumCertificates,
    79  			all.Setups,
    80  			all.EpochCommits,
    81  			all.EpochProtocolState,
    82  			all.ProtocolKVStore,
    83  			all.VersionBeacons,
    84  			rootSnapshot,
    85  		)
    86  		require.NoError(t, err)
    87  		f(db, state)
    88  	})
    89  }
    90  
    91  func RunWithFullProtocolState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.ParticipantState)) {
    92  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
    93  		metrics := metrics.NewNoopCollector()
    94  		tracer := trace.NewNoopTracer()
    95  		log := zerolog.Nop()
    96  		consumer := events.NewNoop()
    97  		all := util.StorageLayer(t, db)
    98  		state, err := pbadger.Bootstrap(
    99  			metrics,
   100  			db,
   101  			all.Headers,
   102  			all.Seals,
   103  			all.Results,
   104  			all.Blocks,
   105  			all.QuorumCertificates,
   106  			all.Setups,
   107  			all.EpochCommits,
   108  			all.EpochProtocolState,
   109  			all.ProtocolKVStore,
   110  			all.VersionBeacons,
   111  			rootSnapshot,
   112  		)
   113  		require.NoError(t, err)
   114  		receiptValidator := MockReceiptValidator()
   115  		sealValidator := MockSealValidator(all.Seals)
   116  		mockTimer := MockBlockTimer()
   117  		fullState, err := pbadger.NewFullConsensusState(
   118  			log,
   119  			tracer,
   120  			consumer,
   121  			state,
   122  			all.Index,
   123  			all.Payloads,
   124  			mockTimer,
   125  			receiptValidator,
   126  			sealValidator,
   127  		)
   128  		require.NoError(t, err)
   129  		f(db, fullState)
   130  	})
   131  }
   132  
   133  func RunWithFullProtocolStateAndMetrics(t testing.TB, rootSnapshot protocol.Snapshot, metrics module.ComplianceMetrics, f func(*badger.DB, *pbadger.ParticipantState)) {
   134  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   135  		tracer := trace.NewNoopTracer()
   136  		log := zerolog.Nop()
   137  		consumer := events.NewNoop()
   138  		all := util.StorageLayer(t, db)
   139  		state, err := pbadger.Bootstrap(
   140  			metrics,
   141  			db,
   142  			all.Headers,
   143  			all.Seals,
   144  			all.Results,
   145  			all.Blocks,
   146  			all.QuorumCertificates,
   147  			all.Setups,
   148  			all.EpochCommits,
   149  			all.EpochProtocolState,
   150  			all.ProtocolKVStore,
   151  			all.VersionBeacons,
   152  			rootSnapshot,
   153  		)
   154  		require.NoError(t, err)
   155  		receiptValidator := MockReceiptValidator()
   156  		sealValidator := MockSealValidator(all.Seals)
   157  		mockTimer := MockBlockTimer()
   158  		fullState, err := pbadger.NewFullConsensusState(
   159  			log,
   160  			tracer,
   161  			consumer,
   162  			state,
   163  			all.Index,
   164  			all.Payloads,
   165  			mockTimer,
   166  			receiptValidator,
   167  			sealValidator,
   168  		)
   169  		require.NoError(t, err)
   170  		f(db, fullState)
   171  	})
   172  }
   173  
   174  func RunWithFullProtocolStateAndValidator(t testing.TB, rootSnapshot protocol.Snapshot, validator module.ReceiptValidator, f func(*badger.DB, *pbadger.ParticipantState)) {
   175  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   176  		metrics := metrics.NewNoopCollector()
   177  		tracer := trace.NewNoopTracer()
   178  		log := zerolog.Nop()
   179  		consumer := events.NewNoop()
   180  		all := util.StorageLayer(t, db)
   181  		state, err := pbadger.Bootstrap(
   182  			metrics,
   183  			db,
   184  			all.Headers,
   185  			all.Seals,
   186  			all.Results,
   187  			all.Blocks,
   188  			all.QuorumCertificates,
   189  			all.Setups,
   190  			all.EpochCommits,
   191  			all.EpochProtocolState,
   192  			all.ProtocolKVStore,
   193  			all.VersionBeacons,
   194  			rootSnapshot,
   195  		)
   196  		require.NoError(t, err)
   197  		sealValidator := MockSealValidator(all.Seals)
   198  		mockTimer := MockBlockTimer()
   199  		fullState, err := pbadger.NewFullConsensusState(
   200  			log,
   201  			tracer,
   202  			consumer,
   203  			state,
   204  			all.Index,
   205  			all.Payloads,
   206  			mockTimer,
   207  			validator,
   208  			sealValidator,
   209  		)
   210  		require.NoError(t, err)
   211  		f(db, fullState)
   212  	})
   213  }
   214  
   215  func RunWithFollowerProtocolState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.FollowerState)) {
   216  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   217  		metrics := metrics.NewNoopCollector()
   218  		tracer := trace.NewNoopTracer()
   219  		log := zerolog.Nop()
   220  		consumer := events.NewNoop()
   221  		all := util.StorageLayer(t, db)
   222  		state, err := pbadger.Bootstrap(
   223  			metrics,
   224  			db,
   225  			all.Headers,
   226  			all.Seals,
   227  			all.Results,
   228  			all.Blocks,
   229  			all.QuorumCertificates,
   230  			all.Setups,
   231  			all.EpochCommits,
   232  			all.EpochProtocolState,
   233  			all.ProtocolKVStore,
   234  			all.VersionBeacons,
   235  			rootSnapshot,
   236  		)
   237  		require.NoError(t, err)
   238  		mockTimer := MockBlockTimer()
   239  		followerState, err := pbadger.NewFollowerState(
   240  			log,
   241  			tracer,
   242  			consumer,
   243  			state,
   244  			all.Index,
   245  			all.Payloads,
   246  			mockTimer,
   247  		)
   248  		require.NoError(t, err)
   249  		f(db, followerState)
   250  	})
   251  }
   252  
   253  func RunWithFullProtocolStateAndConsumer(t testing.TB, rootSnapshot protocol.Snapshot, consumer protocol.Consumer, f func(*badger.DB, *pbadger.ParticipantState)) {
   254  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   255  		metrics := metrics.NewNoopCollector()
   256  		tracer := trace.NewNoopTracer()
   257  		log := zerolog.Nop()
   258  		all := util.StorageLayer(t, db)
   259  		state, err := pbadger.Bootstrap(
   260  			metrics,
   261  			db,
   262  			all.Headers,
   263  			all.Seals,
   264  			all.Results,
   265  			all.Blocks,
   266  			all.QuorumCertificates,
   267  			all.Setups,
   268  			all.EpochCommits,
   269  			all.EpochProtocolState,
   270  			all.ProtocolKVStore,
   271  			all.VersionBeacons,
   272  			rootSnapshot,
   273  		)
   274  		require.NoError(t, err)
   275  		receiptValidator := MockReceiptValidator()
   276  		sealValidator := MockSealValidator(all.Seals)
   277  		mockTimer := MockBlockTimer()
   278  		fullState, err := pbadger.NewFullConsensusState(
   279  			log,
   280  			tracer,
   281  			consumer,
   282  			state,
   283  			all.Index,
   284  			all.Payloads,
   285  			mockTimer,
   286  			receiptValidator,
   287  			sealValidator,
   288  		)
   289  		require.NoError(t, err)
   290  		f(db, fullState)
   291  	})
   292  }
   293  
   294  func RunWithFullProtocolStateAndMetricsAndConsumer(t testing.TB, rootSnapshot protocol.Snapshot, metrics module.ComplianceMetrics, consumer protocol.Consumer, f func(*badger.DB, *pbadger.ParticipantState, protocol.MutableProtocolState)) {
   295  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   296  		tracer := trace.NewNoopTracer()
   297  		log := zerolog.Nop()
   298  		all := util.StorageLayer(t, db)
   299  		state, err := pbadger.Bootstrap(
   300  			metrics,
   301  			db,
   302  			all.Headers,
   303  			all.Seals,
   304  			all.Results,
   305  			all.Blocks,
   306  			all.QuorumCertificates,
   307  			all.Setups,
   308  			all.EpochCommits,
   309  			all.EpochProtocolState,
   310  			all.ProtocolKVStore,
   311  			all.VersionBeacons,
   312  			rootSnapshot,
   313  		)
   314  		require.NoError(t, err)
   315  		receiptValidator := MockReceiptValidator()
   316  		sealValidator := MockSealValidator(all.Seals)
   317  		mockTimer := MockBlockTimer()
   318  		fullState, err := pbadger.NewFullConsensusState(
   319  			log,
   320  			tracer,
   321  			consumer,
   322  			state,
   323  			all.Index,
   324  			all.Payloads,
   325  			mockTimer,
   326  			receiptValidator,
   327  			sealValidator,
   328  		)
   329  		require.NoError(t, err)
   330  		mutableProtocolState := protocol_state.NewMutableProtocolState(
   331  			all.EpochProtocolState,
   332  			all.ProtocolKVStore,
   333  			state.Params(),
   334  			all.Headers,
   335  			all.Results,
   336  			all.Setups,
   337  			all.EpochCommits,
   338  		)
   339  		f(db, fullState, mutableProtocolState)
   340  	})
   341  }
   342  
   343  func RunWithFollowerProtocolStateAndHeaders(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.FollowerState, storage.Headers, storage.Index)) {
   344  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   345  		metrics := metrics.NewNoopCollector()
   346  		tracer := trace.NewNoopTracer()
   347  		log := zerolog.Nop()
   348  		consumer := events.NewNoop()
   349  		all := util.StorageLayer(t, db)
   350  		state, err := pbadger.Bootstrap(
   351  			metrics,
   352  			db,
   353  			all.Headers,
   354  			all.Seals,
   355  			all.Results,
   356  			all.Blocks,
   357  			all.QuorumCertificates,
   358  			all.Setups,
   359  			all.EpochCommits,
   360  			all.EpochProtocolState,
   361  			all.ProtocolKVStore,
   362  			all.VersionBeacons,
   363  			rootSnapshot,
   364  		)
   365  		require.NoError(t, err)
   366  		mockTimer := MockBlockTimer()
   367  		followerState, err := pbadger.NewFollowerState(
   368  			log,
   369  			tracer,
   370  			consumer,
   371  			state,
   372  			all.Index,
   373  			all.Payloads,
   374  			mockTimer,
   375  		)
   376  		require.NoError(t, err)
   377  		f(db, followerState, all.Headers, all.Index)
   378  	})
   379  }
   380  
   381  func RunWithFullProtocolStateAndMutator(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.ParticipantState, protocol.MutableProtocolState)) {
   382  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   383  		metrics := metrics.NewNoopCollector()
   384  		tracer := trace.NewNoopTracer()
   385  		log := zerolog.Nop()
   386  		consumer := events.NewNoop()
   387  		all := util.StorageLayer(t, db)
   388  		state, err := pbadger.Bootstrap(
   389  			metrics,
   390  			db,
   391  			all.Headers,
   392  			all.Seals,
   393  			all.Results,
   394  			all.Blocks,
   395  			all.QuorumCertificates,
   396  			all.Setups,
   397  			all.EpochCommits,
   398  			all.EpochProtocolState,
   399  			all.ProtocolKVStore,
   400  			all.VersionBeacons,
   401  			rootSnapshot,
   402  		)
   403  		require.NoError(t, err)
   404  		receiptValidator := MockReceiptValidator()
   405  		sealValidator := MockSealValidator(all.Seals)
   406  		mockTimer := MockBlockTimer()
   407  		fullState, err := pbadger.NewFullConsensusState(
   408  			log,
   409  			tracer,
   410  			consumer,
   411  			state,
   412  			all.Index,
   413  			all.Payloads,
   414  			mockTimer,
   415  			receiptValidator,
   416  			sealValidator,
   417  		)
   418  		require.NoError(t, err)
   419  		mutableProtocolState := protocol_state.NewMutableProtocolState(
   420  			all.EpochProtocolState,
   421  			all.ProtocolKVStore,
   422  			state.Params(),
   423  			all.Headers,
   424  			all.Results,
   425  			all.Setups,
   426  			all.EpochCommits,
   427  		)
   428  		f(db, fullState, mutableProtocolState)
   429  	})
   430  }