github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/powchain/log_processing_test.go (about)

     1  package powchain
     2  
     3  import (
     4  	"context"
     5  	"encoding/binary"
     6  	"math/big"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/ethereum/go-ethereum"
    11  	"github.com/ethereum/go-ethereum/common"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
    14  	statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
    15  	"github.com/prysmaticlabs/prysm/beacon-chain/db"
    16  	testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    17  	mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
    18  	contracts "github.com/prysmaticlabs/prysm/contracts/deposit-contract"
    19  	"github.com/prysmaticlabs/prysm/shared/params"
    20  	"github.com/prysmaticlabs/prysm/shared/testutil"
    21  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    22  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    23  	logTest "github.com/sirupsen/logrus/hooks/test"
    24  )
    25  
    26  func TestProcessDepositLog_OK(t *testing.T) {
    27  	hook := logTest.NewGlobal()
    28  
    29  	testAcc, err := contracts.Setup()
    30  	require.NoError(t, err, "Unable to set up simulated backend")
    31  
    32  	beaconDB := testDB.SetupDB(t)
    33  	depositCache, err := depositcache.New()
    34  	require.NoError(t, err)
    35  
    36  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
    37  		HttpEndpoints:   []string{endpoint},
    38  		DepositContract: testAcc.ContractAddr,
    39  		BeaconDB:        beaconDB,
    40  		DepositCache:    depositCache,
    41  	})
    42  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
    43  	web3Service = setDefaultMocks(web3Service)
    44  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
    45  	require.NoError(t, err)
    46  
    47  	testAcc.Backend.Commit()
    48  
    49  	deposits, _, err := testutil.DeterministicDepositsAndKeys(1)
    50  	require.NoError(t, err)
    51  
    52  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
    53  	require.NoError(t, err)
    54  	data := deposits[0].Data
    55  
    56  	testAcc.TxOpts.Value = contracts.Amount32Eth()
    57  	testAcc.TxOpts.GasLimit = 1000000
    58  	_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[0])
    59  	require.NoError(t, err, "Could not deposit to deposit contract")
    60  
    61  	testAcc.Backend.Commit()
    62  
    63  	query := ethereum.FilterQuery{
    64  		Addresses: []common.Address{
    65  			web3Service.cfg.DepositContract,
    66  		},
    67  	}
    68  
    69  	logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query)
    70  	require.NoError(t, err, "Unable to retrieve logs")
    71  
    72  	if len(logs) == 0 {
    73  		t.Fatal("no logs")
    74  	}
    75  
    76  	err = web3Service.ProcessLog(context.Background(), logs[0])
    77  	require.NoError(t, err)
    78  
    79  	require.LogsDoNotContain(t, hook, "Could not unpack log")
    80  	require.LogsDoNotContain(t, hook, "Could not save in trie")
    81  	require.LogsDoNotContain(t, hook, "could not deserialize validator public key")
    82  	require.LogsDoNotContain(t, hook, "could not convert bytes to signature")
    83  	require.LogsDoNotContain(t, hook, "could not sign root for deposit data")
    84  	require.LogsDoNotContain(t, hook, "deposit signature did not verify")
    85  	require.LogsDoNotContain(t, hook, "could not tree hash deposit data")
    86  	require.LogsDoNotContain(t, hook, "deposit merkle branch of deposit root did not verify for root")
    87  	require.LogsContain(t, hook, "Deposit registered from deposit contract")
    88  
    89  	hook.Reset()
    90  }
    91  
    92  func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) {
    93  	hook := logTest.NewGlobal()
    94  	testAcc, err := contracts.Setup()
    95  	require.NoError(t, err, "Unable to set up simulated backend")
    96  	beaconDB := testDB.SetupDB(t)
    97  	depositCache, err := depositcache.New()
    98  	require.NoError(t, err)
    99  
   100  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   101  		HttpEndpoints:   []string{endpoint},
   102  		DepositContract: testAcc.ContractAddr,
   103  		BeaconDB:        beaconDB,
   104  		DepositCache:    depositCache,
   105  	})
   106  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   107  	web3Service = setDefaultMocks(web3Service)
   108  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   109  	require.NoError(t, err)
   110  
   111  	testAcc.Backend.Commit()
   112  
   113  	deposits, _, err := testutil.DeterministicDepositsAndKeys(1)
   114  	require.NoError(t, err)
   115  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
   116  	require.NoError(t, err)
   117  	data := deposits[0].Data
   118  
   119  	testAcc.TxOpts.Value = contracts.Amount32Eth()
   120  	testAcc.TxOpts.GasLimit = 1000000
   121  
   122  	_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[0])
   123  	require.NoError(t, err, "Could not deposit to deposit contract")
   124  
   125  	_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[0])
   126  	require.NoError(t, err, "Could not deposit to deposit contract")
   127  
   128  	testAcc.Backend.Commit()
   129  
   130  	query := ethereum.FilterQuery{
   131  		Addresses: []common.Address{
   132  			web3Service.cfg.DepositContract,
   133  		},
   134  	}
   135  
   136  	logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query)
   137  	require.NoError(t, err, "Unable to retrieve logs")
   138  
   139  	web3Service.chainStartData.Chainstarted = true
   140  
   141  	err = web3Service.ProcessDepositLog(context.Background(), logs[0])
   142  	require.NoError(t, err)
   143  	err = web3Service.ProcessDepositLog(context.Background(), logs[1])
   144  	require.NoError(t, err)
   145  
   146  	pendingDeposits := web3Service.cfg.DepositCache.PendingDeposits(context.Background(), nil /*blockNum*/)
   147  	require.Equal(t, 2, len(pendingDeposits), "Unexpected number of deposits")
   148  
   149  	hook.Reset()
   150  }
   151  
   152  func TestUnpackDepositLogData_OK(t *testing.T) {
   153  	testAcc, err := contracts.Setup()
   154  	require.NoError(t, err, "Unable to set up simulated backend")
   155  	beaconDB := testDB.SetupDB(t)
   156  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   157  		HttpEndpoints:   []string{endpoint},
   158  		BeaconDB:        beaconDB,
   159  		DepositContract: testAcc.ContractAddr,
   160  	})
   161  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   162  	web3Service = setDefaultMocks(web3Service)
   163  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   164  	require.NoError(t, err)
   165  
   166  	testAcc.Backend.Commit()
   167  
   168  	deposits, _, err := testutil.DeterministicDepositsAndKeys(1)
   169  	require.NoError(t, err)
   170  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
   171  	require.NoError(t, err)
   172  	data := deposits[0].Data
   173  
   174  	testAcc.TxOpts.Value = contracts.Amount32Eth()
   175  	testAcc.TxOpts.GasLimit = 1000000
   176  	_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[0])
   177  	require.NoError(t, err, "Could not deposit to deposit contract")
   178  	testAcc.Backend.Commit()
   179  
   180  	query := ethereum.FilterQuery{
   181  		Addresses: []common.Address{
   182  			web3Service.cfg.DepositContract,
   183  		},
   184  	}
   185  
   186  	logz, err := testAcc.Backend.FilterLogs(web3Service.ctx, query)
   187  	require.NoError(t, err, "Unable to retrieve logs")
   188  
   189  	loggedPubkey, withCreds, _, loggedSig, index, err := contracts.UnpackDepositLogData(logz[0].Data)
   190  	require.NoError(t, err, "Unable to unpack logs")
   191  
   192  	require.Equal(t, uint64(0), binary.LittleEndian.Uint64(index), "Retrieved merkle tree index is incorrect")
   193  	require.DeepEqual(t, data.PublicKey, loggedPubkey, "Pubkey is not the same as the data that was put in")
   194  	require.DeepEqual(t, data.Signature, loggedSig, "Proof of Possession is not the same as the data that was put in")
   195  	require.DeepEqual(t, data.WithdrawalCredentials, withCreds, "Withdrawal Credentials is not the same as the data that was put in")
   196  }
   197  
   198  func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) {
   199  	hook := logTest.NewGlobal()
   200  	testAcc, err := contracts.Setup()
   201  	require.NoError(t, err, "Unable to set up simulated backend")
   202  	beaconDB := testDB.SetupDB(t)
   203  	depositCache, err := depositcache.New()
   204  	require.NoError(t, err)
   205  
   206  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   207  		HttpEndpoints:   []string{endpoint},
   208  		DepositContract: testAcc.ContractAddr,
   209  		BeaconDB:        beaconDB,
   210  		DepositCache:    depositCache,
   211  	})
   212  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   213  	web3Service = setDefaultMocks(web3Service)
   214  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   215  	require.NoError(t, err)
   216  
   217  	params.SetupTestConfigCleanup(t)
   218  	bConfig := params.MinimalSpecConfig()
   219  	bConfig.MinGenesisTime = 0
   220  	params.OverrideBeaconConfig(bConfig)
   221  
   222  	testAcc.Backend.Commit()
   223  	require.NoError(t, testAcc.Backend.AdjustTime(time.Duration(int64(time.Now().Nanosecond()))))
   224  
   225  	deposits, _, err := testutil.DeterministicDepositsAndKeys(1)
   226  	require.NoError(t, err)
   227  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
   228  	require.NoError(t, err)
   229  	data := deposits[0].Data
   230  
   231  	testAcc.TxOpts.Value = contracts.Amount32Eth()
   232  	testAcc.TxOpts.GasLimit = 1000000
   233  
   234  	// 64 Validators are used as size required for beacon-chain to start. This number
   235  	// is defined in the deposit contract as the number required for the testnet. The actual number
   236  	// is 2**14
   237  	for i := 0; i < depositsReqForChainStart; i++ {
   238  		testAcc.TxOpts.Value = contracts.Amount32Eth()
   239  		_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[0])
   240  		require.NoError(t, err, "Could not deposit to deposit contract")
   241  
   242  		testAcc.Backend.Commit()
   243  	}
   244  
   245  	query := ethereum.FilterQuery{
   246  		Addresses: []common.Address{
   247  			web3Service.cfg.DepositContract,
   248  		},
   249  	}
   250  
   251  	logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query)
   252  	require.NoError(t, err, "Unable to retrieve logs")
   253  
   254  	for _, log := range logs {
   255  		err = web3Service.ProcessLog(context.Background(), log)
   256  		require.NoError(t, err)
   257  	}
   258  	assert.Equal(t, false, web3Service.chainStartData.Chainstarted, "Genesis has been triggered despite being 8 duplicate keys")
   259  
   260  	require.LogsDoNotContain(t, hook, "Minimum number of validators reached for beacon-chain to start")
   261  	hook.Reset()
   262  }
   263  
   264  func TestProcessETH2GenesisLog(t *testing.T) {
   265  	params.SetupTestConfigCleanup(t)
   266  	cfg := params.BeaconConfig()
   267  	cfg.GenesisDelay = 0
   268  	params.OverrideBeaconConfig(cfg)
   269  	hook := logTest.NewGlobal()
   270  	testAcc, err := contracts.Setup()
   271  	require.NoError(t, err, "Unable to set up simulated backend")
   272  	beaconDB := testDB.SetupDB(t)
   273  	depositCache, err := depositcache.New()
   274  	require.NoError(t, err)
   275  
   276  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   277  		HttpEndpoints:   []string{endpoint},
   278  		DepositContract: testAcc.ContractAddr,
   279  		BeaconDB:        beaconDB,
   280  		DepositCache:    depositCache,
   281  	})
   282  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   283  	web3Service = setDefaultMocks(web3Service)
   284  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   285  	require.NoError(t, err)
   286  	params.SetupTestConfigCleanup(t)
   287  	bConfig := params.MinimalSpecConfig()
   288  	bConfig.MinGenesisTime = 0
   289  	params.OverrideBeaconConfig(bConfig)
   290  
   291  	testAcc.Backend.Commit()
   292  	require.NoError(t, testAcc.Backend.AdjustTime(time.Duration(int64(time.Now().Nanosecond()))))
   293  
   294  	deposits, _, err := testutil.DeterministicDepositsAndKeys(uint64(depositsReqForChainStart))
   295  	require.NoError(t, err)
   296  	_, roots, err := testutil.DeterministicDepositTrie(len(deposits))
   297  	require.NoError(t, err)
   298  
   299  	// 64 Validators are used as size required for beacon-chain to start. This number
   300  	// is defined in the deposit contract as the number required for the testnet. The actual number
   301  	// is 2**14
   302  	for i := 0; i < depositsReqForChainStart; i++ {
   303  		data := deposits[i].Data
   304  		testAcc.TxOpts.Value = contracts.Amount32Eth()
   305  		testAcc.TxOpts.GasLimit = 1000000
   306  		_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, roots[i])
   307  		require.NoError(t, err, "Could not deposit to deposit contract")
   308  
   309  		testAcc.Backend.Commit()
   310  	}
   311  
   312  	query := ethereum.FilterQuery{
   313  		Addresses: []common.Address{
   314  			web3Service.cfg.DepositContract,
   315  		},
   316  	}
   317  
   318  	logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query)
   319  	require.NoError(t, err, "Unable to retrieve logs")
   320  	require.Equal(t, depositsReqForChainStart, len(logs))
   321  
   322  	// Set up our subscriber now to listen for the chain started event.
   323  	stateChannel := make(chan *feed.Event, 1)
   324  	stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
   325  	defer stateSub.Unsubscribe()
   326  
   327  	for _, log := range logs {
   328  		err = web3Service.ProcessLog(context.Background(), log)
   329  		require.NoError(t, err)
   330  	}
   331  
   332  	err = web3Service.ProcessETH1Block(context.Background(), big.NewInt(int64(logs[len(logs)-1].BlockNumber)))
   333  	require.NoError(t, err)
   334  
   335  	cachedDeposits := web3Service.ChainStartDeposits()
   336  	require.Equal(t, depositsReqForChainStart, len(cachedDeposits))
   337  
   338  	// Receive the chain started event.
   339  	for started := false; !started; {
   340  		event := <-stateChannel
   341  		if event.Type == statefeed.ChainStarted {
   342  			started = true
   343  		}
   344  	}
   345  
   346  	require.LogsDoNotContain(t, hook, "Unable to unpack ChainStart log data")
   347  	require.LogsDoNotContain(t, hook, "Receipt root from log doesn't match the root saved in memory")
   348  	require.LogsDoNotContain(t, hook, "Invalid timestamp from log")
   349  	require.LogsContain(t, hook, "Minimum number of validators reached for beacon-chain to start")
   350  
   351  	hook.Reset()
   352  }
   353  
   354  func TestProcessETH2GenesisLog_CorrectNumOfDeposits(t *testing.T) {
   355  	hook := logTest.NewGlobal()
   356  	testAcc, err := contracts.Setup()
   357  	require.NoError(t, err, "Unable to set up simulated backend")
   358  	kvStore := testDB.SetupDB(t)
   359  	depositCache, err := depositcache.New()
   360  	require.NoError(t, err)
   361  
   362  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   363  		HttpEndpoints:   []string{endpoint},
   364  		DepositContract: testAcc.ContractAddr,
   365  		BeaconDB:        kvStore,
   366  		DepositCache:    depositCache,
   367  	})
   368  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   369  	web3Service = setDefaultMocks(web3Service)
   370  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   371  	require.NoError(t, err)
   372  	web3Service.rpcClient = &mockPOW.RPCClient{Backend: testAcc.Backend}
   373  	web3Service.httpLogger = testAcc.Backend
   374  	web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
   375  	web3Service.latestEth1Data.LastRequestedBlock = 0
   376  	web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().NumberU64()
   377  	web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time()
   378  	params.SetupTestConfigCleanup(t)
   379  	bConfig := params.MinimalSpecConfig()
   380  	bConfig.MinGenesisTime = 0
   381  	bConfig.SecondsPerETH1Block = 10
   382  	params.OverrideBeaconConfig(bConfig)
   383  	nConfig := params.BeaconNetworkConfig()
   384  	nConfig.ContractDeploymentBlock = 0
   385  	params.OverrideBeaconNetworkConfig(nConfig)
   386  
   387  	testAcc.Backend.Commit()
   388  
   389  	totalNumOfDeposits := depositsReqForChainStart + 30
   390  
   391  	deposits, _, err := testutil.DeterministicDepositsAndKeys(uint64(totalNumOfDeposits))
   392  	require.NoError(t, err)
   393  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
   394  	require.NoError(t, err)
   395  	depositOffset := 5
   396  
   397  	// 64 Validators are used as size required for beacon-chain to start. This number
   398  	// is defined in the deposit contract as the number required for the testnet. The actual number
   399  	// is 2**14
   400  	for i := 0; i < totalNumOfDeposits; i++ {
   401  		data := deposits[i].Data
   402  		testAcc.TxOpts.Value = contracts.Amount32Eth()
   403  		testAcc.TxOpts.GasLimit = 1000000
   404  		_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[i])
   405  		require.NoError(t, err, "Could not deposit to deposit contract")
   406  		// pack 8 deposits into a block with an offset of
   407  		// 5
   408  		if (i+1)%8 == depositOffset {
   409  			testAcc.Backend.Commit()
   410  		}
   411  	}
   412  	// Forward the chain to account for the follow distance
   413  	for i := uint64(0); i < params.BeaconConfig().Eth1FollowDistance; i++ {
   414  		testAcc.Backend.Commit()
   415  	}
   416  	web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().NumberU64()
   417  	web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time()
   418  
   419  	// Set up our subscriber now to listen for the chain started event.
   420  	stateChannel := make(chan *feed.Event, 1)
   421  	stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
   422  	defer stateSub.Unsubscribe()
   423  
   424  	err = web3Service.processPastLogs(context.Background())
   425  	require.NoError(t, err)
   426  
   427  	cachedDeposits := web3Service.ChainStartDeposits()
   428  	requiredDepsForChainstart := depositsReqForChainStart + depositOffset
   429  	require.Equal(t, requiredDepsForChainstart, len(cachedDeposits), "Did not cache the chain start deposits correctly")
   430  
   431  	// Receive the chain started event.
   432  	for started := false; !started; {
   433  		event := <-stateChannel
   434  		if event.Type == statefeed.ChainStarted {
   435  			started = true
   436  		}
   437  	}
   438  
   439  	require.LogsDoNotContain(t, hook, "Unable to unpack ChainStart log data")
   440  	require.LogsDoNotContain(t, hook, "Receipt root from log doesn't match the root saved in memory")
   441  	require.LogsDoNotContain(t, hook, "Invalid timestamp from log")
   442  	require.LogsContain(t, hook, "Minimum number of validators reached for beacon-chain to start")
   443  
   444  	hook.Reset()
   445  }
   446  
   447  func TestProcessETH2GenesisLog_LargePeriodOfNoLogs(t *testing.T) {
   448  	hook := logTest.NewGlobal()
   449  	testAcc, err := contracts.Setup()
   450  	require.NoError(t, err, "Unable to set up simulated backend")
   451  	kvStore := testDB.SetupDB(t)
   452  	depositCache, err := depositcache.New()
   453  	require.NoError(t, err)
   454  
   455  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   456  		HttpEndpoints:   []string{endpoint},
   457  		DepositContract: testAcc.ContractAddr,
   458  		BeaconDB:        kvStore,
   459  		DepositCache:    depositCache,
   460  	})
   461  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   462  	web3Service = setDefaultMocks(web3Service)
   463  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
   464  	require.NoError(t, err)
   465  	web3Service.rpcClient = &mockPOW.RPCClient{Backend: testAcc.Backend}
   466  	web3Service.httpLogger = testAcc.Backend
   467  	web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
   468  	web3Service.latestEth1Data.LastRequestedBlock = 0
   469  	web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().NumberU64()
   470  	web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time()
   471  	params.SetupTestConfigCleanup(t)
   472  	bConfig := params.MinimalSpecConfig()
   473  	bConfig.SecondsPerETH1Block = 10
   474  	params.OverrideBeaconConfig(bConfig)
   475  	nConfig := params.BeaconNetworkConfig()
   476  	nConfig.ContractDeploymentBlock = 0
   477  	params.OverrideBeaconNetworkConfig(nConfig)
   478  
   479  	testAcc.Backend.Commit()
   480  
   481  	totalNumOfDeposits := depositsReqForChainStart + 30
   482  
   483  	deposits, _, err := testutil.DeterministicDepositsAndKeys(uint64(totalNumOfDeposits))
   484  	require.NoError(t, err)
   485  	_, depositRoots, err := testutil.DeterministicDepositTrie(len(deposits))
   486  	require.NoError(t, err)
   487  	depositOffset := 5
   488  
   489  	// 64 Validators are used as size required for beacon-chain to start. This number
   490  	// is defined in the deposit contract as the number required for the testnet. The actual number
   491  	// is 2**14
   492  	for i := 0; i < totalNumOfDeposits; i++ {
   493  		data := deposits[i].Data
   494  		testAcc.TxOpts.Value = contracts.Amount32Eth()
   495  		testAcc.TxOpts.GasLimit = 1000000
   496  		_, err = testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoots[i])
   497  		require.NoError(t, err, "Could not deposit to deposit contract")
   498  		// pack 8 deposits into a block with an offset of
   499  		// 5
   500  		if (i+1)%8 == depositOffset {
   501  			testAcc.Backend.Commit()
   502  		}
   503  	}
   504  	// Forward the chain to 'mine' blocks without logs
   505  	for i := uint64(0); i < 1500; i++ {
   506  		testAcc.Backend.Commit()
   507  	}
   508  	wantedGenesisTime := testAcc.Backend.Blockchain().CurrentBlock().Time()
   509  
   510  	// Forward the chain to account for the follow distance
   511  	for i := uint64(0); i < params.BeaconConfig().Eth1FollowDistance; i++ {
   512  		testAcc.Backend.Commit()
   513  	}
   514  	web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().NumberU64()
   515  	web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time()
   516  
   517  	// Set the genesis time 500 blocks ahead of the last
   518  	// deposit log.
   519  	bConfig = params.MinimalSpecConfig()
   520  	bConfig.MinGenesisTime = wantedGenesisTime - 10
   521  	params.OverrideBeaconConfig(bConfig)
   522  
   523  	// Set up our subscriber now to listen for the chain started event.
   524  	stateChannel := make(chan *feed.Event, 1)
   525  	stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
   526  	defer stateSub.Unsubscribe()
   527  
   528  	err = web3Service.processPastLogs(context.Background())
   529  	require.NoError(t, err)
   530  
   531  	cachedDeposits := web3Service.ChainStartDeposits()
   532  	require.Equal(t, totalNumOfDeposits, len(cachedDeposits), "Did not cache the chain start deposits correctly")
   533  
   534  	// Receive the chain started event.
   535  	for started := false; !started; {
   536  		event := <-stateChannel
   537  		if event.Type == statefeed.ChainStarted {
   538  			started = true
   539  		}
   540  	}
   541  
   542  	require.LogsDoNotContain(t, hook, "Unable to unpack ChainStart log data")
   543  	require.LogsDoNotContain(t, hook, "Receipt root from log doesn't match the root saved in memory")
   544  	require.LogsDoNotContain(t, hook, "Invalid timestamp from log")
   545  	require.LogsContain(t, hook, "Minimum number of validators reached for beacon-chain to start")
   546  
   547  	hook.Reset()
   548  }
   549  
   550  func TestCheckForChainstart_NoValidator(t *testing.T) {
   551  	hook := logTest.NewGlobal()
   552  	testAcc, err := contracts.Setup()
   553  	require.NoError(t, err, "Unable to set up simulated backend")
   554  	beaconDB := testDB.SetupDB(t)
   555  	s := newPowchainService(t, testAcc, beaconDB)
   556  	s.checkForChainstart([32]byte{}, nil, 0)
   557  	require.LogsDoNotContain(t, hook, "Could not determine active validator count from pre genesis state")
   558  }
   559  
   560  func newPowchainService(t *testing.T, eth1Backend *contracts.TestAccount, beaconDB db.Database) *Service {
   561  	depositCache, err := depositcache.New()
   562  	require.NoError(t, err)
   563  
   564  	web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
   565  		HttpEndpoints:   []string{endpoint},
   566  		DepositContract: eth1Backend.ContractAddr,
   567  		BeaconDB:        beaconDB,
   568  		DepositCache:    depositCache,
   569  	})
   570  	require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
   571  	web3Service = setDefaultMocks(web3Service)
   572  	web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(eth1Backend.ContractAddr, eth1Backend.Backend)
   573  	require.NoError(t, err)
   574  
   575  	web3Service.rpcClient = &mockPOW.RPCClient{Backend: eth1Backend.Backend}
   576  	web3Service.eth1DataFetcher = &goodFetcher{backend: eth1Backend.Backend}
   577  	web3Service.httpLogger = &goodLogger{backend: eth1Backend.Backend}
   578  	params.SetupTestConfigCleanup(t)
   579  	bConfig := params.MinimalSpecConfig()
   580  	bConfig.MinGenesisTime = 0
   581  	params.OverrideBeaconConfig(bConfig)
   582  	return web3Service
   583  }