github.com/onflow/flow-go@v0.33.17/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  	"github.com/onflow/flow-go/storage"
    21  	"github.com/onflow/flow-go/storage/util"
    22  	"github.com/onflow/flow-go/utils/unittest"
    23  )
    24  
    25  // MockReceiptValidator returns a ReceiptValidator that accepts
    26  // all receipts without performing any
    27  // integrity checks.
    28  func MockReceiptValidator() module.ReceiptValidator {
    29  	validator := &modulemock.ReceiptValidator{}
    30  	validator.On("Validate", mock.Anything).Return(nil)
    31  	validator.On("ValidatePayload", mock.Anything).Return(nil)
    32  	return validator
    33  }
    34  
    35  // MockBlockTimer returns BlockTimer that accepts all timestamps
    36  // without performing any checks.
    37  func MockBlockTimer() protocol.BlockTimer {
    38  	blockTimer := &mockprotocol.BlockTimer{}
    39  	blockTimer.On("Validate", mock.Anything, mock.Anything).Return(nil)
    40  	return blockTimer
    41  }
    42  
    43  // MockSealValidator returns a SealValidator that accepts
    44  // all seals without performing any
    45  // integrity checks, returns first seal in block as valid one
    46  func MockSealValidator(sealsDB storage.Seals) module.SealValidator {
    47  	validator := &modulemock.SealValidator{}
    48  	validator.On("Validate", mock.Anything).Return(
    49  		func(candidate *flow.Block) *flow.Seal {
    50  			if len(candidate.Payload.Seals) > 0 {
    51  				return candidate.Payload.Seals[0]
    52  			}
    53  			last, _ := sealsDB.HighestInFork(candidate.Header.ParentID)
    54  			return last
    55  		},
    56  		func(candidate *flow.Block) error {
    57  			if len(candidate.Payload.Seals) > 0 {
    58  				return nil
    59  			}
    60  			_, err := sealsDB.HighestInFork(candidate.Header.ParentID)
    61  			return err
    62  		}).Maybe()
    63  	return validator
    64  }
    65  
    66  func RunWithBootstrapState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.State)) {
    67  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
    68  		metrics := metrics.NewNoopCollector()
    69  		all := util.StorageLayer(t, db)
    70  		state, err := pbadger.Bootstrap(
    71  			metrics,
    72  			db,
    73  			all.Headers,
    74  			all.Seals,
    75  			all.Results,
    76  			all.Blocks,
    77  			all.QuorumCertificates,
    78  			all.Setups,
    79  			all.EpochCommits,
    80  			all.Statuses,
    81  			all.VersionBeacons,
    82  			rootSnapshot,
    83  		)
    84  		require.NoError(t, err)
    85  		f(db, state)
    86  	})
    87  }
    88  
    89  func RunWithFullProtocolState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.ParticipantState)) {
    90  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
    91  		metrics := metrics.NewNoopCollector()
    92  		tracer := trace.NewNoopTracer()
    93  		log := zerolog.Nop()
    94  		consumer := events.NewNoop()
    95  		all := util.StorageLayer(t, db)
    96  		state, err := pbadger.Bootstrap(
    97  			metrics,
    98  			db,
    99  			all.Headers,
   100  			all.Seals,
   101  			all.Results,
   102  			all.Blocks,
   103  			all.QuorumCertificates,
   104  			all.Setups,
   105  			all.EpochCommits,
   106  			all.Statuses,
   107  			all.VersionBeacons,
   108  			rootSnapshot,
   109  		)
   110  		require.NoError(t, err)
   111  		receiptValidator := MockReceiptValidator()
   112  		sealValidator := MockSealValidator(all.Seals)
   113  		mockTimer := MockBlockTimer()
   114  		fullState, err := pbadger.NewFullConsensusState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer, receiptValidator, sealValidator)
   115  		require.NoError(t, err)
   116  		f(db, fullState)
   117  	})
   118  }
   119  
   120  func RunWithFullProtocolStateAndMetrics(t testing.TB, rootSnapshot protocol.Snapshot, metrics module.ComplianceMetrics, f func(*badger.DB, *pbadger.ParticipantState)) {
   121  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   122  		tracer := trace.NewNoopTracer()
   123  		log := zerolog.Nop()
   124  		consumer := events.NewNoop()
   125  		all := util.StorageLayer(t, db)
   126  		state, err := pbadger.Bootstrap(
   127  			metrics,
   128  			db,
   129  			all.Headers,
   130  			all.Seals,
   131  			all.Results,
   132  			all.Blocks,
   133  			all.QuorumCertificates,
   134  			all.Setups,
   135  			all.EpochCommits,
   136  			all.Statuses,
   137  			all.VersionBeacons,
   138  			rootSnapshot,
   139  		)
   140  		require.NoError(t, err)
   141  		receiptValidator := MockReceiptValidator()
   142  		sealValidator := MockSealValidator(all.Seals)
   143  		mockTimer := MockBlockTimer()
   144  		fullState, err := pbadger.NewFullConsensusState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer, receiptValidator, sealValidator)
   145  		require.NoError(t, err)
   146  		f(db, fullState)
   147  	})
   148  }
   149  
   150  func RunWithFullProtocolStateAndValidator(t testing.TB, rootSnapshot protocol.Snapshot, validator module.ReceiptValidator, f func(*badger.DB, *pbadger.ParticipantState)) {
   151  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   152  		metrics := metrics.NewNoopCollector()
   153  		tracer := trace.NewNoopTracer()
   154  		log := zerolog.Nop()
   155  		consumer := events.NewNoop()
   156  		all := util.StorageLayer(t, db)
   157  		state, err := pbadger.Bootstrap(
   158  			metrics,
   159  			db,
   160  			all.Headers,
   161  			all.Seals,
   162  			all.Results,
   163  			all.Blocks,
   164  			all.QuorumCertificates,
   165  			all.Setups,
   166  			all.EpochCommits,
   167  			all.Statuses,
   168  			all.VersionBeacons,
   169  			rootSnapshot,
   170  		)
   171  		require.NoError(t, err)
   172  		sealValidator := MockSealValidator(all.Seals)
   173  		mockTimer := MockBlockTimer()
   174  		fullState, err := pbadger.NewFullConsensusState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer, validator, sealValidator)
   175  		require.NoError(t, err)
   176  		f(db, fullState)
   177  	})
   178  }
   179  
   180  func RunWithFollowerProtocolState(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.FollowerState)) {
   181  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   182  		metrics := metrics.NewNoopCollector()
   183  		tracer := trace.NewNoopTracer()
   184  		log := zerolog.Nop()
   185  		consumer := events.NewNoop()
   186  		all := util.StorageLayer(t, db)
   187  		state, err := pbadger.Bootstrap(
   188  			metrics,
   189  			db,
   190  			all.Headers,
   191  			all.Seals,
   192  			all.Results,
   193  			all.Blocks,
   194  			all.QuorumCertificates,
   195  			all.Setups,
   196  			all.EpochCommits,
   197  			all.Statuses,
   198  			all.VersionBeacons,
   199  			rootSnapshot,
   200  		)
   201  		require.NoError(t, err)
   202  		mockTimer := MockBlockTimer()
   203  		followerState, err := pbadger.NewFollowerState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer)
   204  		require.NoError(t, err)
   205  		f(db, followerState)
   206  	})
   207  }
   208  
   209  func RunWithFullProtocolStateAndConsumer(t testing.TB, rootSnapshot protocol.Snapshot, consumer protocol.Consumer, f func(*badger.DB, *pbadger.ParticipantState)) {
   210  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   211  		metrics := metrics.NewNoopCollector()
   212  		tracer := trace.NewNoopTracer()
   213  		log := zerolog.Nop()
   214  		all := util.StorageLayer(t, db)
   215  		state, err := pbadger.Bootstrap(
   216  			metrics,
   217  			db,
   218  			all.Headers,
   219  			all.Seals,
   220  			all.Results,
   221  			all.Blocks,
   222  			all.QuorumCertificates,
   223  			all.Setups,
   224  			all.EpochCommits,
   225  			all.Statuses,
   226  			all.VersionBeacons,
   227  			rootSnapshot,
   228  		)
   229  		require.NoError(t, err)
   230  		receiptValidator := MockReceiptValidator()
   231  		sealValidator := MockSealValidator(all.Seals)
   232  		mockTimer := MockBlockTimer()
   233  		fullState, err := pbadger.NewFullConsensusState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer, receiptValidator, sealValidator)
   234  		require.NoError(t, err)
   235  		f(db, fullState)
   236  	})
   237  }
   238  
   239  func RunWithFullProtocolStateAndMetricsAndConsumer(t testing.TB, rootSnapshot protocol.Snapshot, metrics module.ComplianceMetrics, consumer protocol.Consumer, f func(*badger.DB, *pbadger.ParticipantState)) {
   240  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   241  		tracer := trace.NewNoopTracer()
   242  		log := zerolog.Nop()
   243  		all := util.StorageLayer(t, db)
   244  		state, err := pbadger.Bootstrap(
   245  			metrics,
   246  			db,
   247  			all.Headers,
   248  			all.Seals,
   249  			all.Results,
   250  			all.Blocks,
   251  			all.QuorumCertificates,
   252  			all.Setups,
   253  			all.EpochCommits,
   254  			all.Statuses,
   255  			all.VersionBeacons,
   256  			rootSnapshot,
   257  		)
   258  		require.NoError(t, err)
   259  		receiptValidator := MockReceiptValidator()
   260  		sealValidator := MockSealValidator(all.Seals)
   261  		mockTimer := MockBlockTimer()
   262  		fullState, err := pbadger.NewFullConsensusState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer, receiptValidator, sealValidator)
   263  		require.NoError(t, err)
   264  		f(db, fullState)
   265  	})
   266  }
   267  
   268  func RunWithFollowerProtocolStateAndHeaders(t testing.TB, rootSnapshot protocol.Snapshot, f func(*badger.DB, *pbadger.FollowerState, storage.Headers, storage.Index)) {
   269  	unittest.RunWithBadgerDB(t, func(db *badger.DB) {
   270  		metrics := metrics.NewNoopCollector()
   271  		tracer := trace.NewNoopTracer()
   272  		log := zerolog.Nop()
   273  		consumer := events.NewNoop()
   274  		all := util.StorageLayer(t, db)
   275  		state, err := pbadger.Bootstrap(
   276  			metrics,
   277  			db,
   278  			all.Headers,
   279  			all.Seals,
   280  			all.Results,
   281  			all.Blocks,
   282  			all.QuorumCertificates,
   283  			all.Setups,
   284  			all.EpochCommits,
   285  			all.Statuses,
   286  			all.VersionBeacons,
   287  			rootSnapshot,
   288  		)
   289  		require.NoError(t, err)
   290  		mockTimer := MockBlockTimer()
   291  		followerState, err := pbadger.NewFollowerState(log, tracer, consumer, state, all.Index, all.Payloads, mockTimer)
   292  		require.NoError(t, err)
   293  		f(db, followerState, all.Headers, all.Index)
   294  	})
   295  }