mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Initialize Data Correctly For Powchain Service (#8812)
* initialize index correctly * comments * review comments * Update beacon-chain/powchain/service.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
package powchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@@ -220,20 +221,8 @@ func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to retrieve eth1 data")
|
||||
}
|
||||
if eth1Data != nil {
|
||||
s.depositTrie = trieutil.CreateTrieFromProto(eth1Data.Trie)
|
||||
s.chainStartData = eth1Data.ChainstartData
|
||||
if !reflect.ValueOf(eth1Data.BeaconState).IsZero() {
|
||||
s.preGenesisState, err = stateV0.InitializeFromProto(eth1Data.BeaconState)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Could not initialize state trie")
|
||||
}
|
||||
}
|
||||
s.latestEth1Data = eth1Data.CurrentEth1Data
|
||||
s.lastReceivedMerkleIndex = int64(len(s.depositTrie.Items()) - 1)
|
||||
if err := s.initDepositCaches(ctx, eth1Data.DepositContainers); err != nil {
|
||||
return nil, errors.Wrap(err, "could not initialize caches")
|
||||
}
|
||||
if err := s.initializeEth1Data(ctx, eth1Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
@@ -936,6 +925,53 @@ func (s *Service) fallbackToNextEndpoint() {
|
||||
log.Infof("Falling back to alternative endpoint: %s", logutil.MaskCredentialsLogging(s.currHttpEndpoint.Url))
|
||||
}
|
||||
|
||||
// initializes our service from the provided eth1data object by initializing all the relevant
|
||||
// fields and data.
|
||||
func (s *Service) initializeEth1Data(ctx context.Context, eth1DataInDB *protodb.ETH1ChainData) error {
|
||||
// The node has no eth1data persisted on disk, so we exit and instead
|
||||
// request from contract logs.
|
||||
if eth1DataInDB == nil {
|
||||
return nil
|
||||
}
|
||||
s.depositTrie = trieutil.CreateTrieFromProto(eth1DataInDB.Trie)
|
||||
s.chainStartData = eth1DataInDB.ChainstartData
|
||||
var err error
|
||||
if !reflect.ValueOf(eth1DataInDB.BeaconState).IsZero() {
|
||||
s.preGenesisState, err = stateV0.InitializeFromProto(eth1DataInDB.BeaconState)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not initialize state trie")
|
||||
}
|
||||
}
|
||||
s.latestEth1Data = eth1DataInDB.CurrentEth1Data
|
||||
items := s.depositTrie.Items()
|
||||
s.lastReceivedMerkleIndex = int64(len(items) - 1)
|
||||
// Account for 0 elements existing in the deposit trie.
|
||||
if len(items) == 1 && bytes.Equal(items[0], params.BeaconConfig().ZeroHash[:]) {
|
||||
s.lastReceivedMerkleIndex = -1
|
||||
}
|
||||
if err := s.initDepositCaches(ctx, eth1DataInDB.DepositContainers); err != nil {
|
||||
return errors.Wrap(err, "could not initialize caches")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validates that all deposit containers are valid and have their relevant indices
|
||||
// in order.
|
||||
func (s *Service) validateDepositContainers(ctrs []*protodb.DepositContainer) bool {
|
||||
ctrLen := len(ctrs)
|
||||
// Exit for empty containers.
|
||||
if ctrLen == 0 {
|
||||
return true
|
||||
}
|
||||
for _, c := range ctrs {
|
||||
if c.Index == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
log.Info("Recovering missing deposit containers, node is re-requesting missing deposit data")
|
||||
return false
|
||||
}
|
||||
|
||||
// validates the current powchain data saved and makes sure that any
|
||||
// embedded genesis state is correctly accounted for.
|
||||
func (s *Service) ensureValidPowchainData(ctx context.Context) error {
|
||||
@@ -951,7 +987,7 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to retrieve eth1 data")
|
||||
}
|
||||
if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted {
|
||||
if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted || !s.validateDepositContainers(eth1Data.DepositContainers) {
|
||||
pbState, err := stateV0.ProtobufBeaconState(s.preGenesisState.InnerStateUnsafe())
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -620,6 +620,83 @@ func TestService_EnsureConsistentPowchainData(t *testing.T) {
|
||||
assert.Equal(t, true, eth1Data.ChainstartData.Chainstarted)
|
||||
}
|
||||
|
||||
func TestService_InitializeCorrectly(t *testing.T) {
|
||||
beaconDB := dbutil.SetupDB(t)
|
||||
cache, err := depositcache.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
s1, err := NewService(context.Background(), &Web3ServiceConfig{
|
||||
BeaconDB: beaconDB,
|
||||
DepositCache: cache,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
genState, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, genState.SetSlot(1000))
|
||||
|
||||
require.NoError(t, s1.cfg.BeaconDB.SaveGenesisData(context.Background(), genState))
|
||||
require.NoError(t, s1.ensureValidPowchainData(context.Background()))
|
||||
|
||||
eth1Data, err := s1.cfg.BeaconDB.PowchainData(context.Background())
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, s1.initializeEth1Data(context.Background(), eth1Data))
|
||||
assert.Equal(t, int64(-1), s1.lastReceivedMerkleIndex, "received incorrect last received merkle index")
|
||||
}
|
||||
|
||||
func TestService_EnsureValidPowchainData(t *testing.T) {
|
||||
beaconDB := dbutil.SetupDB(t)
|
||||
cache, err := depositcache.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
s1, err := NewService(context.Background(), &Web3ServiceConfig{
|
||||
BeaconDB: beaconDB,
|
||||
DepositCache: cache,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
genState, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, genState.SetSlot(1000))
|
||||
|
||||
require.NoError(t, s1.cfg.BeaconDB.SaveGenesisData(context.Background(), genState))
|
||||
|
||||
err = s1.cfg.BeaconDB.SavePowchainData(context.Background(), &protodb.ETH1ChainData{
|
||||
ChainstartData: &protodb.ChainStartData{Chainstarted: true},
|
||||
DepositContainers: []*protodb.DepositContainer{{Index: 1}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s1.ensureValidPowchainData(context.Background()))
|
||||
|
||||
eth1Data, err := s1.cfg.BeaconDB.PowchainData(context.Background())
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NotNil(t, eth1Data)
|
||||
assert.Equal(t, 0, len(eth1Data.DepositContainers))
|
||||
}
|
||||
|
||||
func TestService_ValidateDepositContainers(t *testing.T) {
|
||||
beaconDB := dbutil.SetupDB(t)
|
||||
cache, err := depositcache.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
s1, err := NewService(context.Background(), &Web3ServiceConfig{
|
||||
BeaconDB: beaconDB,
|
||||
DepositCache: cache,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
ctrs := make([]*protodb.DepositContainer, 0)
|
||||
assert.Equal(t, true, s1.validateDepositContainers(ctrs))
|
||||
for i := 0; i < 10; i++ {
|
||||
ctrs = append(ctrs, &protodb.DepositContainer{Index: int64(i), Eth1BlockHeight: uint64(i + 10)})
|
||||
}
|
||||
assert.Equal(t, true, s1.validateDepositContainers(ctrs))
|
||||
ctrs = make([]*protodb.DepositContainer, 0)
|
||||
for i := 1; i < 10; i++ {
|
||||
ctrs = append(ctrs, &protodb.DepositContainer{Index: int64(i), Eth1BlockHeight: uint64(i + 10)})
|
||||
}
|
||||
assert.Equal(t, false, s1.validateDepositContainers(ctrs))
|
||||
}
|
||||
|
||||
func TestTimestampIsChecked(t *testing.T) {
|
||||
timestamp := uint64(time.Now().Unix())
|
||||
assert.Equal(t, false, eth1HeadIsBehind(timestamp))
|
||||
|
||||
Reference in New Issue
Block a user