github.com/koko1123/flow-go-1@v0.29.6/engine/testutil/mock/nodes.go (about)

     1  package mock
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"sync"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/dgraph-io/badger/v3"
    11  	"github.com/rs/zerolog"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/koko1123/flow-go-1/engine/collection/epochmgr"
    15  	collectioningest "github.com/koko1123/flow-go-1/engine/collection/ingest"
    16  	"github.com/koko1123/flow-go-1/engine/collection/pusher"
    17  	followereng "github.com/koko1123/flow-go-1/engine/common/follower"
    18  	"github.com/koko1123/flow-go-1/engine/common/provider"
    19  	"github.com/koko1123/flow-go-1/engine/common/requester"
    20  	"github.com/koko1123/flow-go-1/engine/common/synchronization"
    21  	consensusingest "github.com/koko1123/flow-go-1/engine/consensus/ingestion"
    22  	"github.com/koko1123/flow-go-1/engine/consensus/matching"
    23  	"github.com/koko1123/flow-go-1/engine/consensus/sealing"
    24  	"github.com/koko1123/flow-go-1/engine/execution"
    25  	"github.com/koko1123/flow-go-1/engine/execution/computation"
    26  	"github.com/koko1123/flow-go-1/engine/execution/ingestion"
    27  	executionprovider "github.com/koko1123/flow-go-1/engine/execution/provider"
    28  	"github.com/koko1123/flow-go-1/engine/execution/state"
    29  	"github.com/koko1123/flow-go-1/engine/verification/assigner"
    30  	"github.com/koko1123/flow-go-1/engine/verification/assigner/blockconsumer"
    31  	"github.com/koko1123/flow-go-1/engine/verification/fetcher"
    32  	"github.com/koko1123/flow-go-1/engine/verification/fetcher/chunkconsumer"
    33  	verificationrequester "github.com/koko1123/flow-go-1/engine/verification/requester"
    34  	"github.com/koko1123/flow-go-1/engine/verification/verifier"
    35  	"github.com/koko1123/flow-go-1/fvm"
    36  	fvmState "github.com/koko1123/flow-go-1/fvm/state"
    37  	"github.com/koko1123/flow-go-1/ledger"
    38  	"github.com/koko1123/flow-go-1/ledger/complete"
    39  	"github.com/koko1123/flow-go-1/model/flow"
    40  	"github.com/koko1123/flow-go-1/module"
    41  	"github.com/koko1123/flow-go-1/module/finalizer/consensus"
    42  	"github.com/koko1123/flow-go-1/module/irrecoverable"
    43  	"github.com/koko1123/flow-go-1/module/mempool"
    44  	"github.com/koko1123/flow-go-1/module/mempool/entity"
    45  	epochpool "github.com/koko1123/flow-go-1/module/mempool/epochs"
    46  	"github.com/koko1123/flow-go-1/module/metrics"
    47  	"github.com/koko1123/flow-go-1/module/util"
    48  	"github.com/koko1123/flow-go-1/network/stub"
    49  	"github.com/koko1123/flow-go-1/state/protocol"
    50  	"github.com/koko1123/flow-go-1/state/protocol/events"
    51  	"github.com/koko1123/flow-go-1/storage"
    52  	bstorage "github.com/koko1123/flow-go-1/storage/badger"
    53  	"github.com/koko1123/flow-go-1/utils/unittest"
    54  )
    55  
    56  // StateFixture is a test helper struct that encapsulates a flow protocol state
    57  // as well as all of its backend dependencies.
    58  type StateFixture struct {
    59  	DBDir          string
    60  	PublicDB       *badger.DB
    61  	SecretsDB      *badger.DB
    62  	Storage        *storage.All
    63  	ProtocolEvents *events.Distributor
    64  	State          protocol.MutableState
    65  }
    66  
    67  // GenericNode implements a generic in-process node for tests.
    68  type GenericNode struct {
    69  	// context and cancel function used to start/stop components
    70  	Ctx    irrecoverable.SignalerContext
    71  	Cancel context.CancelFunc
    72  
    73  	Log            zerolog.Logger
    74  	Metrics        *metrics.NoopCollector
    75  	Tracer         module.Tracer
    76  	PublicDB       *badger.DB
    77  	SecretsDB      *badger.DB
    78  	Headers        storage.Headers
    79  	Guarantees     storage.Guarantees
    80  	Seals          storage.Seals
    81  	Payloads       storage.Payloads
    82  	Blocks         storage.Blocks
    83  	State          protocol.MutableState
    84  	Index          storage.Index
    85  	Me             module.Local
    86  	Net            *stub.Network
    87  	DBDir          string
    88  	ChainID        flow.ChainID
    89  	ProtocolEvents *events.Distributor
    90  }
    91  
    92  func (g *GenericNode) Done() {
    93  	_ = g.PublicDB.Close()
    94  	_ = os.RemoveAll(g.DBDir)
    95  
    96  	<-g.Tracer.Done()
    97  }
    98  
    99  // RequireGenericNodesDoneBefore invokes the done method of all input generic nodes concurrently, and
   100  // fails the test if any generic node's shutdown takes longer than the specified duration.
   101  func RequireGenericNodesDoneBefore(t testing.TB, duration time.Duration, nodes ...*GenericNode) {
   102  	wg := &sync.WaitGroup{}
   103  	wg.Add(len(nodes))
   104  
   105  	for _, node := range nodes {
   106  		go func(n *GenericNode) {
   107  			n.Done()
   108  			wg.Done()
   109  		}(node)
   110  	}
   111  
   112  	unittest.RequireReturnsBefore(t, wg.Wait, duration, "failed to shutdown all components on time")
   113  }
   114  
   115  // CloseDB closes the badger database of the node
   116  func (g *GenericNode) CloseDB() error {
   117  	return g.PublicDB.Close()
   118  }
   119  
   120  // CollectionNode implements an in-process collection node for tests.
   121  type CollectionNode struct {
   122  	GenericNode
   123  	Collections        storage.Collections
   124  	Transactions       storage.Transactions
   125  	ClusterPayloads    storage.ClusterPayloads
   126  	TxPools            *epochpool.TransactionPools
   127  	Voter              module.ClusterRootQCVoter
   128  	IngestionEngine    *collectioningest.Engine
   129  	PusherEngine       *pusher.Engine
   130  	ProviderEngine     *provider.Engine
   131  	EpochManagerEngine *epochmgr.Engine
   132  }
   133  
   134  func (n CollectionNode) Ready() <-chan struct{} {
   135  	n.IngestionEngine.Start(n.Ctx)
   136  	return util.AllReady(
   137  		n.PusherEngine,
   138  		n.ProviderEngine,
   139  		n.IngestionEngine,
   140  		n.EpochManagerEngine,
   141  	)
   142  }
   143  
   144  func (n CollectionNode) Done() <-chan struct{} {
   145  	done := make(chan struct{})
   146  	go func() {
   147  		n.GenericNode.Cancel()
   148  		<-util.AllDone(
   149  			n.PusherEngine,
   150  			n.ProviderEngine,
   151  			n.IngestionEngine,
   152  			n.EpochManagerEngine,
   153  		)
   154  		n.GenericNode.Done()
   155  		close(done)
   156  	}()
   157  	return done
   158  }
   159  
   160  // ConsensusNode implements an in-process consensus node for tests.
   161  type ConsensusNode struct {
   162  	GenericNode
   163  	Guarantees      mempool.Guarantees
   164  	Receipts        mempool.ExecutionTree
   165  	Seals           mempool.IncorporatedResultSeals
   166  	IngestionEngine *consensusingest.Engine
   167  	SealingEngine   *sealing.Engine
   168  	MatchingEngine  *matching.Engine
   169  }
   170  
   171  func (cn ConsensusNode) Ready() {
   172  	<-cn.IngestionEngine.Ready()
   173  	<-cn.SealingEngine.Ready()
   174  }
   175  
   176  func (cn ConsensusNode) Done() {
   177  	<-cn.IngestionEngine.Done()
   178  	<-cn.SealingEngine.Done()
   179  }
   180  
   181  type ComputerWrap struct {
   182  	*computation.Manager
   183  	OnComputeBlock func(ctx context.Context, block *entity.ExecutableBlock, view fvmState.View)
   184  }
   185  
   186  func (c *ComputerWrap) ComputeBlock(
   187  	ctx context.Context,
   188  	block *entity.ExecutableBlock,
   189  	view fvmState.View,
   190  ) (*execution.ComputationResult, error) {
   191  	if c.OnComputeBlock != nil {
   192  		c.OnComputeBlock(ctx, block, view)
   193  	}
   194  	return c.Manager.ComputeBlock(ctx, block, view)
   195  }
   196  
   197  // ExecutionNode implements a mocked execution node for tests.
   198  type ExecutionNode struct {
   199  	GenericNode
   200  	MutableState        protocol.MutableState
   201  	IngestionEngine     *ingestion.Engine
   202  	ExecutionEngine     *ComputerWrap
   203  	RequestEngine       *requester.Engine
   204  	ReceiptsEngine      *executionprovider.Engine
   205  	FollowerEngine      *followereng.Engine
   206  	SyncEngine          *synchronization.Engine
   207  	Compactor           *complete.Compactor
   208  	BadgerDB            *badger.DB
   209  	VM                  fvm.VM
   210  	ExecutionState      state.ExecutionState
   211  	Ledger              ledger.Ledger
   212  	LevelDbDir          string
   213  	Collections         storage.Collections
   214  	Finalizer           *consensus.Finalizer
   215  	MyExecutionReceipts storage.MyExecutionReceipts
   216  }
   217  
   218  func (en ExecutionNode) Ready(ctx context.Context) {
   219  	// TODO: receipt engine has been migrated to the new component interface, hence
   220  	// is using Start. Other engines' startup should be refactored once migrated to
   221  	// new interface.
   222  	irctx, _ := irrecoverable.WithSignaler(ctx)
   223  	en.ReceiptsEngine.Start(irctx)
   224  
   225  	<-util.AllReady(
   226  		en.Ledger,
   227  		en.ReceiptsEngine,
   228  		en.IngestionEngine,
   229  		en.FollowerEngine,
   230  		en.RequestEngine,
   231  		en.SyncEngine,
   232  	)
   233  }
   234  
   235  func (en ExecutionNode) Done(cancelFunc context.CancelFunc) {
   236  	// to stop all components running with a component manager.
   237  	cancelFunc()
   238  
   239  	// to stop all (deprecated) ready-done-aware
   240  	<-util.AllDone(
   241  		en.IngestionEngine,
   242  		en.IngestionEngine,
   243  		en.ReceiptsEngine,
   244  		en.Ledger,
   245  		en.FollowerEngine,
   246  		en.RequestEngine,
   247  		en.SyncEngine,
   248  		en.Compactor,
   249  	)
   250  	os.RemoveAll(en.LevelDbDir)
   251  	en.GenericNode.Done()
   252  }
   253  
   254  func (en ExecutionNode) AssertHighestExecutedBlock(t *testing.T, header *flow.Header) {
   255  
   256  	height, blockID, err := en.ExecutionState.GetHighestExecutedBlockID(context.Background())
   257  	require.NoError(t, err)
   258  
   259  	require.Equal(t, header.ID(), blockID)
   260  	require.Equal(t, header.Height, height)
   261  }
   262  
   263  // VerificationNode implements an in-process verification node for tests.
   264  type VerificationNode struct {
   265  	*GenericNode
   266  	ChunkStatuses mempool.ChunkStatuses
   267  	ChunkRequests mempool.ChunkRequests
   268  	Results       storage.ExecutionResults
   269  	Receipts      storage.ExecutionReceipts
   270  
   271  	// chunk consumer and processor for fetcher engine
   272  	ProcessedChunkIndex storage.ConsumerProgress
   273  	ChunksQueue         *bstorage.ChunksQueue
   274  	ChunkConsumer       *chunkconsumer.ChunkConsumer
   275  
   276  	// block consumer for chunk consumer
   277  	ProcessedBlockHeight storage.ConsumerProgress
   278  	BlockConsumer        *blockconsumer.BlockConsumer
   279  
   280  	VerifierEngine  *verifier.Engine
   281  	AssignerEngine  *assigner.Engine
   282  	FetcherEngine   *fetcher.Engine
   283  	RequesterEngine *verificationrequester.Engine
   284  }