code.vegaprotocol.io/vega@v0.79.0/datanode/broker/sqlstore_broker_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package broker_test
    17  
    18  import (
    19  	"context"
    20  	"encoding/hex"
    21  	"sync"
    22  	"testing"
    23  	"time"
    24  
    25  	"code.vegaprotocol.io/vega/core/events"
    26  	"code.vegaprotocol.io/vega/core/types"
    27  	"code.vegaprotocol.io/vega/datanode/broker"
    28  	"code.vegaprotocol.io/vega/datanode/entities"
    29  	"code.vegaprotocol.io/vega/datanode/networkhistory"
    30  	"code.vegaprotocol.io/vega/datanode/service"
    31  	vgcontext "code.vegaprotocol.io/vega/libs/context"
    32  	"code.vegaprotocol.io/vega/logging"
    33  	eventsv1 "code.vegaprotocol.io/vega/protos/vega/events/v1"
    34  
    35  	"github.com/pkg/errors"
    36  	"github.com/stretchr/testify/assert"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  var logger = logging.NewTestLogger()
    41  
    42  func TestBrokerShutsDownOnErrorFromErrorChannelWhenInRecovery(t *testing.T) {
    43  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
    44  
    45  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1})
    46  
    47  	beSource := newBlockEventSource()
    48  	blockEvent1 := beSource.NextBeginBlockEvent()
    49  	// make sure we move forward by ending the block, but discard as we're not going to use it
    50  	_ = beSource.NextEndBlockEvent()
    51  	blockEvent2 := beSource.NextBeginBlockEvent()
    52  	// make sure we move forward by ending the block, but discard as we're not going to use it
    53  	_ = beSource.NextEndBlockEvent()
    54  
    55  	block1, _ := entities.BlockFromBeginBlock(blockEvent1)
    56  	block2, _ := entities.BlockFromBeginBlock(blockEvent2)
    57  
    58  	blockStore := newTestBlockStore()
    59  
    60  	// Set the block store to have already processed the first 2 blocks
    61  	require.NoError(t, blockStore.Add(context.Background(), *block1))
    62  	require.NoError(t, blockStore.Add(context.Background(), *block2))
    63  
    64  	closedChan := make(chan bool)
    65  	go func() {
    66  		err := sb.Receive(context.Background())
    67  		assert.NotNil(t, err)
    68  		closedChan <- true
    69  	}()
    70  
    71  	tes.eventsCh <- blockEvent1
    72  
    73  	tes.errorsCh <- errors.New("Test error")
    74  }
    75  
    76  func TestBrokerShutsDownOnErrorFromErrorChannel(t *testing.T) {
    77  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
    78  
    79  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1})
    80  
    81  	closedChan := make(chan bool)
    82  	go func() {
    83  		err := sb.Receive(context.Background())
    84  		assert.NotNil(t, err)
    85  		closedChan <- true
    86  	}()
    87  
    88  	beSource := newBlockEventSource()
    89  	tes.eventsCh <- beSource.NextBeginBlockEvent()
    90  
    91  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
    92  
    93  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s1.receivedCh)
    94  
    95  	tes.errorsCh <- errors.New("Test error")
    96  
    97  	assert.Equal(t, true, <-closedChan)
    98  }
    99  
   100  func TestBrokerShutsDownOnErrorWhenInRecovery(t *testing.T) {
   101  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   102  
   103  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1})
   104  
   105  	beSource := newBlockEventSource()
   106  	blockEvent1 := beSource.NextBeginBlockEvent()
   107  	_ = beSource.NextEndBlockEvent()
   108  	blockEvent2 := beSource.NextBeginBlockEvent()
   109  	_ = beSource.NextEndBlockEvent()
   110  	_ = beSource.NextBeginBlockEvent()
   111  	_ = beSource.NextEndBlockEvent()
   112  	blockEvent4 := beSource.NextBeginBlockEvent()
   113  
   114  	block1, _ := entities.BlockFromBeginBlock(blockEvent1)
   115  	block2, _ := entities.BlockFromBeginBlock(blockEvent2)
   116  
   117  	blockStore := newTestBlockStore()
   118  
   119  	// Set the block store to have already processed the first 2 blocks
   120  	blockStore.Add(context.Background(), *block1)
   121  	blockStore.Add(context.Background(), *block2)
   122  
   123  	closedChan := make(chan bool)
   124  	go func() {
   125  		err := sb.Receive(context.Background())
   126  		assert.NotNil(t, err)
   127  		closedChan <- true
   128  	}()
   129  
   130  	tes.eventsCh <- blockEvent4
   131  
   132  	assert.Equal(t, true, <-closedChan)
   133  }
   134  
   135  func TestBrokerShutsDownOnError(t *testing.T) {
   136  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   137  	errorSubscriber := &errorTestSQLBrokerSubscriber{s1}
   138  
   139  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{errorSubscriber})
   140  
   141  	closedChan := make(chan bool)
   142  	go func() {
   143  		err := sb.Receive(context.Background())
   144  		assert.NotNil(t, err)
   145  		closedChan <- true
   146  	}()
   147  
   148  	beSource := newBlockEventSource()
   149  	tes.eventsCh <- beSource.NextBeginBlockEvent()
   150  
   151  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   152  
   153  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s1.receivedCh)
   154  	tes.eventsCh <- beSource.NextEndBlockEvent()
   155  
   156  	assert.Equal(t, true, <-closedChan)
   157  }
   158  
   159  func TestBrokerShutsDownWhenContextCancelledWhenInRecovery(t *testing.T) {
   160  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   161  
   162  	beSource := newBlockEventSource()
   163  	blockEvent1 := beSource.NextBeginBlockEvent()
   164  	_ = beSource.NextEndBlockEvent()
   165  	blockEvent2 := beSource.NextBeginBlockEvent()
   166  	_ = beSource.NextEndBlockEvent()
   167  
   168  	block1, _ := entities.BlockFromBeginBlock(blockEvent1)
   169  	block2, _ := entities.BlockFromBeginBlock(blockEvent2)
   170  
   171  	blockStore := newTestBlockStore()
   172  
   173  	// Set the block store to have already processed the first 2 blocks
   174  	blockStore.Add(context.Background(), *block1)
   175  	blockStore.Add(context.Background(), *block2)
   176  
   177  	tes, sb := createTestBroker(newTestTransactionManager(), blockStore, []broker.SQLBrokerSubscriber{s1})
   178  
   179  	ctx, cancel := context.WithCancel(context.Background())
   180  
   181  	closedChan := make(chan bool)
   182  	go func() {
   183  		sb.Receive(ctx)
   184  		closedChan <- true
   185  	}()
   186  
   187  	tes.eventsCh <- blockEvent1
   188  
   189  	cancel()
   190  
   191  	assert.Equal(t, true, <-closedChan)
   192  }
   193  
   194  func TestBrokerShutsDownWhenContextCancelled(t *testing.T) {
   195  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   196  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1})
   197  	ctx, cancel := context.WithCancel(context.Background())
   198  
   199  	closedChan := make(chan bool)
   200  	go func() {
   201  		sb.Receive(ctx)
   202  		closedChan <- true
   203  	}()
   204  
   205  	beSource := newBlockEventSource()
   206  	tes.eventsCh <- beSource.NextBeginBlockEvent()
   207  
   208  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   209  
   210  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s1.receivedCh)
   211  
   212  	cancel()
   213  
   214  	assert.Equal(t, true, <-closedChan)
   215  }
   216  
   217  func TestAnyEventsSentAheadOfFirstTimeEventAreIgnored(t *testing.T) {
   218  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   219  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1})
   220  	go sb.Receive(context.Background())
   221  
   222  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   223  
   224  	beSource := newBlockEventSource()
   225  	tes.eventsCh <- beSource.NextBeginBlockEvent()
   226  
   227  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"})
   228  
   229  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"}), <-s1.receivedCh)
   230  }
   231  
   232  func TestBlocksSentBeforeStartedAtBlockAreIgnored(t *testing.T) {
   233  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   234  
   235  	beSource := newBlockEventSource()
   236  	blockBeginEvent1 := beSource.NextBeginBlockEvent()
   237  	blockEndEvent1 := beSource.NextEndBlockEvent()
   238  	blockBeginEvent2 := beSource.NextBeginBlockEvent()
   239  	blockEndEvent2 := beSource.NextEndBlockEvent()
   240  	blockBeginEvent3 := beSource.NextBeginBlockEvent()
   241  
   242  	block1, _ := entities.BlockFromBeginBlock(blockBeginEvent1)
   243  	block2, _ := entities.BlockFromBeginBlock(blockBeginEvent2)
   244  
   245  	blockStore := newTestBlockStore()
   246  
   247  	// Set the block store to have already processed the first 2 blocks
   248  	blockStore.Add(context.Background(), *block1)
   249  	blockStore.Add(context.Background(), *block2)
   250  
   251  	tes, sb := createTestBroker(newTestTransactionManager(), blockStore, []broker.SQLBrokerSubscriber{s1})
   252  	go sb.Receive(context.Background())
   253  
   254  	tes.eventsCh <- blockBeginEvent1
   255  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   256  	tes.eventsCh <- blockEndEvent1
   257  	tes.eventsCh <- blockBeginEvent2
   258  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"})
   259  	tes.eventsCh <- blockEndEvent2
   260  	tes.eventsCh <- blockBeginEvent3
   261  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a3"})
   262  
   263  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a3"}), <-s1.receivedCh)
   264  }
   265  
   266  func TestTimeUpdateWithTooHighHeightCauseFailure(t *testing.T) {
   267  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   268  
   269  	beSource := newBlockEventSource()
   270  	blockEvent1 := beSource.NextBeginBlockEvent()
   271  	_ = beSource.NextEndBlockEvent()
   272  	blockEvent2 := beSource.NextBeginBlockEvent()
   273  	_ = beSource.NextEndBlockEvent()
   274  	_ = beSource.NextBeginBlockEvent()
   275  	_ = beSource.NextEndBlockEvent()
   276  	blockEvent4 := beSource.NextBeginBlockEvent()
   277  
   278  	block1, _ := entities.BlockFromBeginBlock(blockEvent1)
   279  	block2, _ := entities.BlockFromBeginBlock(blockEvent2)
   280  
   281  	blockStore := newTestBlockStore()
   282  
   283  	// Set the block store to have already processed the first 2 blocks
   284  	blockStore.Add(context.Background(), *block1)
   285  	blockStore.Add(context.Background(), *block2)
   286  
   287  	tes, sb := createTestBroker(newTestTransactionManager(), blockStore, []broker.SQLBrokerSubscriber{s1})
   288  
   289  	errCh := make(chan error)
   290  	go func() {
   291  		err := sb.Receive(context.Background())
   292  		errCh <- err
   293  	}()
   294  
   295  	tes.eventsCh <- blockEvent4
   296  
   297  	assert.NotNil(t, <-errCh)
   298  }
   299  
   300  func TestSqlBrokerSubscriberCallbacks(t *testing.T) {
   301  	s1 := testSQLBrokerSubscriber{
   302  		eventType:  events.AssetEvent,
   303  		receivedCh: make(chan events.Event, 1),
   304  		vegaTimeCh: make(chan time.Time),
   305  		flushCh:    make(chan bool),
   306  	}
   307  
   308  	transactionManager := newTestTransactionManager()
   309  	transactionManager.withTransactionCalls = make(chan bool)
   310  	transactionManager.withConnectionCalls = make(chan bool, 1)
   311  	transactionManager.commitCall = make(chan bool)
   312  
   313  	blockStore := newTestBlockStore()
   314  
   315  	tes, sb := createTestBroker(transactionManager, blockStore, []broker.SQLBrokerSubscriber{&s1})
   316  
   317  	go sb.Receive(context.Background())
   318  
   319  	beSource := newBlockEventSource()
   320  
   321  	// BlockEnd event should cause a flush of subscribers, followed by commit and then an update to subscribers vegatime,
   322  	// followed by initiating a new transaction and adding a block for the new time
   323  	beginEvent := beSource.NextBeginBlockEvent()
   324  	endEvent := beSource.NextEndBlockEvent()
   325  	tes.eventsCh <- beginEvent
   326  
   327  	assert.Equal(t, time.Unix(0, beginEvent.BeginBlock().Timestamp), <-s1.vegaTimeCh)
   328  	assert.Equal(t, true, <-transactionManager.withTransactionCalls)
   329  	assert.Equal(t, true, <-transactionManager.withConnectionCalls)
   330  
   331  	hash, _ := hex.DecodeString(beginEvent.TraceID())
   332  	expectedBlock := entities.Block{
   333  		VegaTime: time.Unix(0, beginEvent.BeginBlock().Timestamp).Truncate(time.Microsecond),
   334  		Hash:     hash,
   335  		Height:   beginEvent.BlockNr(),
   336  	}
   337  
   338  	assert.Equal(t, expectedBlock, <-blockStore.blocks)
   339  
   340  	tes.eventsCh <- endEvent
   341  	assert.Equal(t, true, <-s1.flushCh)
   342  	assert.Equal(t, true, <-transactionManager.commitCall)
   343  
   344  	beginEvent = beSource.NextBeginBlockEvent()
   345  	endEvent = beSource.NextEndBlockEvent()
   346  	tes.eventsCh <- beginEvent
   347  
   348  	assert.Equal(t, time.Unix(0, beginEvent.BeginBlock().Timestamp).Truncate(time.Microsecond), <-s1.vegaTimeCh)
   349  	assert.Equal(t, true, <-transactionManager.withTransactionCalls)
   350  
   351  	hash, _ = hex.DecodeString(beginEvent.TraceID())
   352  	expectedBlock = entities.Block{
   353  		VegaTime: time.Unix(0, beginEvent.BeginBlock().Timestamp).Truncate(time.Microsecond),
   354  		Hash:     hash,
   355  		Height:   beginEvent.BlockNr(),
   356  	}
   357  
   358  	assert.Equal(t, expectedBlock, <-blockStore.blocks)
   359  
   360  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   361  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s1.receivedCh)
   362  
   363  	tes.eventsCh <- endEvent
   364  
   365  	assert.Equal(t, true, <-s1.flushCh)
   366  	assert.Equal(t, true, <-transactionManager.commitCall)
   367  
   368  	beginEvent = beSource.NextBeginBlockEvent()
   369  	tes.eventsCh <- beginEvent
   370  
   371  	assert.Equal(t, time.Unix(0, beginEvent.BeginBlock().Timestamp).Truncate(time.Microsecond), <-s1.vegaTimeCh)
   372  	assert.Equal(t, true, <-transactionManager.withTransactionCalls)
   373  
   374  	hash, _ = hex.DecodeString(beginEvent.TraceID())
   375  	expectedBlock = entities.Block{
   376  		VegaTime: time.Unix(0, beginEvent.BeginBlock().Timestamp).Truncate(time.Microsecond),
   377  		Hash:     hash,
   378  		Height:   beginEvent.BlockNr(),
   379  	}
   380  
   381  	assert.Equal(t, expectedBlock, <-blockStore.blocks)
   382  }
   383  
   384  func TestSqlBrokerEventDistribution(t *testing.T) {
   385  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   386  	s2 := newTestSQLBrokerSubscriber(events.AssetEvent)
   387  	s3 := newTestSQLBrokerSubscriber(events.AccountEvent)
   388  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1, s2, s3})
   389  	go sb.Receive(context.Background())
   390  
   391  	beSource := newBlockEventSource()
   392  	tes.eventsCh <- beSource.NextBeginBlockEvent()
   393  
   394  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"})
   395  
   396  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s1.receivedCh)
   397  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a1"}), <-s2.receivedCh)
   398  
   399  	tes.eventsCh <- events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"})
   400  
   401  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"}), <-s1.receivedCh)
   402  	assert.Equal(t, events.NewAssetEvent(context.Background(), types.Asset{ID: "a2"}), <-s2.receivedCh)
   403  
   404  	tes.eventsCh <- events.NewAccountEvent(context.Background(), types.Account{ID: "acc1"})
   405  
   406  	assert.Equal(t, events.NewAccountEvent(context.Background(), types.Account{ID: "acc1"}), <-s3.receivedCh)
   407  }
   408  
   409  func TestSqlBrokerTimeEventSentToAllSubscribers(t *testing.T) {
   410  	s1 := newTestSQLBrokerSubscriber(events.AssetEvent)
   411  	s2 := newTestSQLBrokerSubscriber(events.AssetEvent)
   412  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{s1, s2})
   413  
   414  	go sb.Receive(context.Background())
   415  
   416  	beSource := newBlockEventSource()
   417  	blockEvent := beSource.NextBeginBlockEvent()
   418  	tes.eventsCh <- blockEvent
   419  
   420  	assert.Equal(t, time.Unix(0, blockEvent.BeginBlock().Timestamp).
   421  		Truncate(time.Microsecond), <-s1.vegaTimeCh)
   422  	assert.Equal(t, time.Unix(0, blockEvent.BeginBlock().Timestamp).
   423  		Truncate(time.Microsecond), <-s2.vegaTimeCh)
   424  }
   425  
   426  func TestSqlBrokerUpgradeBlock(t *testing.T) {
   427  	tes, sb := createTestBroker(newTestTransactionManager(), newTestBlockStore(), []broker.SQLBrokerSubscriber{})
   428  
   429  	errCh := make(chan error)
   430  	go func() {
   431  		err := sb.Receive(context.Background())
   432  		errCh <- err
   433  	}()
   434  
   435  	beSource := newBlockEventSource()
   436  
   437  	// send through a full block
   438  	blockEvent := beSource.NextBeginBlockEvent()
   439  	tes.eventsCh <- blockEvent
   440  	tes.eventsCh <- beSource.NextEndBlockEvent()
   441  
   442  	// everything gets committed, now we start a new block
   443  	blockEvent = beSource.NextBeginBlockEvent()
   444  	tes.eventsCh <- blockEvent
   445  	assert.False(t, tes.protocolUpgradeSvc.GetProtocolUpgradeStarted())
   446  
   447  	// now protocol upgrade event comes through
   448  	tes.eventsCh <- events.NewProtocolUpgradeStarted(context.Background(), eventsv1.ProtocolUpgradeStarted{
   449  		LastBlockHeight: blockEvent.BeginBlock().Height,
   450  	})
   451  	assert.Nil(t, <-errCh)
   452  	assert.True(t, tes.protocolUpgradeSvc.GetProtocolUpgradeStarted())
   453  }
   454  
   455  func createTestBroker(transactionManager broker.TransactionManager, blockStore broker.BlockStore, subs []broker.SQLBrokerSubscriber) (*testEventSource, broker.SQLStoreEventBroker) {
   456  	conf := broker.NewDefaultConfig()
   457  	log := logging.NewTestLogger()
   458  	tes := &testEventSource{
   459  		eventsCh:           make(chan events.Event),
   460  		errorsCh:           make(chan error, 1),
   461  		protocolUpgradeSvc: service.NewProtocolUpgrade(nil, log),
   462  	}
   463  
   464  	blockCommitedFunc := func(context.Context, string, int64, bool) {}
   465  
   466  	protocolUpgradeHandler := networkhistory.NewProtocolUpgradeHandler(log,
   467  		tes.protocolUpgradeSvc, tes, func(ctx context.Context, chainID string, toHeight int64) error {
   468  			return nil
   469  		})
   470  
   471  	sb := broker.NewSQLStoreBroker(logger, conf, "", tes, transactionManager, blockStore, blockCommitedFunc, protocolUpgradeHandler, subs)
   472  
   473  	return tes, sb
   474  }
   475  
   476  type testBlockStore struct {
   477  	blocks    chan entities.Block
   478  	blockLock sync.Mutex
   479  	lastBlock *entities.Block
   480  }
   481  
   482  func newTestBlockStore() *testBlockStore {
   483  	return &testBlockStore{
   484  		blocks: make(chan entities.Block, 100),
   485  	}
   486  }
   487  
   488  func (t *testBlockStore) Add(ctx context.Context, b entities.Block) error {
   489  	t.blocks <- b
   490  	t.blockLock.Lock()
   491  	defer t.blockLock.Unlock()
   492  	t.lastBlock = &b
   493  
   494  	return nil
   495  }
   496  
   497  func (t *testBlockStore) GetLastBlock(ctx context.Context) (entities.Block, error) {
   498  	t.blockLock.Lock()
   499  	defer t.blockLock.Unlock()
   500  
   501  	if t.lastBlock == nil {
   502  		return entities.Block{}, entities.ErrNotFound
   503  	}
   504  
   505  	return *t.lastBlock, nil
   506  }
   507  
   508  type testTransactionManager struct {
   509  	withTransactionCalls chan bool
   510  	withConnectionCalls  chan bool
   511  	commitCall           chan bool
   512  }
   513  
   514  func newTestTransactionManager() *testTransactionManager {
   515  	return &testTransactionManager{
   516  		withTransactionCalls: make(chan bool, 100),
   517  		withConnectionCalls:  make(chan bool, 100),
   518  		commitCall:           make(chan bool, 100),
   519  	}
   520  }
   521  
   522  func (t *testTransactionManager) WithTransaction(ctx context.Context) (context.Context, error) {
   523  	t.withTransactionCalls <- true
   524  	return ctx, nil
   525  }
   526  
   527  func (t *testTransactionManager) WithConnection(ctx context.Context) (context.Context, error) {
   528  	t.withConnectionCalls <- true
   529  	return ctx, nil
   530  }
   531  
   532  func (t *testTransactionManager) Commit(ctx context.Context) error {
   533  	t.commitCall <- true
   534  	return nil
   535  }
   536  
   537  func (t *testTransactionManager) Rollback(ctx context.Context) error {
   538  	return nil
   539  }
   540  
   541  func (t *testTransactionManager) RefreshMaterializedViews(_ context.Context) error {
   542  	return nil
   543  }
   544  
   545  type errorTestSQLBrokerSubscriber struct {
   546  	*testSQLBrokerSubscriber
   547  }
   548  
   549  func (e *errorTestSQLBrokerSubscriber) Flush(ctx context.Context) error {
   550  	return errors.New("its broken")
   551  }
   552  
   553  type testSQLBrokerSubscriber struct {
   554  	eventType  events.Type
   555  	receivedCh chan events.Event
   556  	flushCh    chan bool
   557  	vegaTimeCh chan time.Time
   558  }
   559  
   560  func newTestSQLBrokerSubscriber(eventType events.Type) *testSQLBrokerSubscriber {
   561  	return &testSQLBrokerSubscriber{
   562  		eventType:  eventType,
   563  		receivedCh: make(chan events.Event, 100),
   564  		flushCh:    make(chan bool, 100),
   565  		vegaTimeCh: make(chan time.Time, 100),
   566  	}
   567  }
   568  
   569  func (t *testSQLBrokerSubscriber) SetVegaTime(vegaTime time.Time) {
   570  	t.vegaTimeCh <- vegaTime
   571  }
   572  
   573  func (t *testSQLBrokerSubscriber) Flush(ctx context.Context) error {
   574  	t.flushCh <- true
   575  	return nil
   576  }
   577  
   578  func (t *testSQLBrokerSubscriber) Push(ctx context.Context, evt events.Event) error {
   579  	t.receivedCh <- evt
   580  	return nil
   581  }
   582  
   583  func (t *testSQLBrokerSubscriber) Types() []events.Type {
   584  	return []events.Type{t.eventType}
   585  }
   586  
   587  func (_ *testSQLBrokerSubscriber) Name() string {
   588  	return "testSQLBrokerSubscriber"
   589  }
   590  
   591  type blockEventSource struct {
   592  	vegaTime    time.Time
   593  	blockHeight uint64
   594  }
   595  
   596  func newBlockEventSource() *blockEventSource {
   597  	return &blockEventSource{
   598  		vegaTime:    time.Now().Truncate(time.Millisecond),
   599  		blockHeight: 1,
   600  	}
   601  }
   602  
   603  func (s *blockEventSource) NextBeginBlockEvent() *events.BeginBlock {
   604  	ctx := vgcontext.WithTraceID(context.Background(), "DEADBEEF")
   605  	ctx = vgcontext.WithBlockHeight(ctx, s.blockHeight)
   606  
   607  	event := events.NewBeginBlock(ctx, eventsv1.BeginBlock{
   608  		Height:    s.blockHeight,
   609  		Timestamp: s.vegaTime.UnixNano(),
   610  	})
   611  
   612  	return event
   613  }
   614  
   615  func (s *blockEventSource) NextEndBlockEvent() *events.EndBlock {
   616  	ctx := vgcontext.WithTraceID(context.Background(), "DEADBEEF")
   617  	ctx = vgcontext.WithBlockHeight(ctx, s.blockHeight)
   618  
   619  	event := events.NewEndBlock(ctx, eventsv1.EndBlock{
   620  		Height: s.blockHeight,
   621  	})
   622  
   623  	s.vegaTime = s.vegaTime.Add(1 * time.Second)
   624  	s.blockHeight++
   625  
   626  	return event
   627  }