mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 11:32:09 +00:00
Fix VC DB conversion when no proposer settings is defined and add Experimental
flag in the --enable-minimal-slashing-protection
help. (#13691)
* VC: Allow DB conversion without proposer settings. * `enable-minimal-slashing-protection` flag: Add `Experimental warning`.
This commit is contained in:
parent
ee9274a9bc
commit
21775eed52
@ -97,7 +97,7 @@ var (
|
|||||||
}
|
}
|
||||||
EnableMinimalSlashingProtection = &cli.BoolFlag{
|
EnableMinimalSlashingProtection = &cli.BoolFlag{
|
||||||
Name: "enable-minimal-slashing-protection",
|
Name: "enable-minimal-slashing-protection",
|
||||||
Usage: "Enables the minimal slashing protection. See EIP-3076 for more details.",
|
Usage: "(Experimental): Enables the minimal slashing protection. See EIP-3076 for more details.",
|
||||||
}
|
}
|
||||||
enableDoppelGangerProtection = &cli.BoolFlag{
|
enableDoppelGangerProtection = &cli.BoolFlag{
|
||||||
Name: "enable-doppelganger",
|
Name: "enable-doppelganger",
|
||||||
|
@ -124,13 +124,18 @@ func ConvertDatabase(ctx context.Context, sourceDataDir string, targetDataDir st
|
|||||||
// -----------------
|
// -----------------
|
||||||
// Get the proposer settings.
|
// Get the proposer settings.
|
||||||
proposerSettings, err := sourceDatabase.ProposerSettings(ctx)
|
proposerSettings, err := sourceDatabase.ProposerSettings(ctx)
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not get proposer settings from source database")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the proposer settings.
|
switch err {
|
||||||
if err := targetDatabase.SaveProposerSettings(ctx, proposerSettings); err != nil {
|
case nil:
|
||||||
return errors.Wrap(err, "could not save proposer settings")
|
// Save the proposer settings.
|
||||||
|
if err := targetDatabase.SaveProposerSettings(ctx, proposerSettings); err != nil {
|
||||||
|
return errors.Wrap(err, "could not save proposer settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
case kv.ErrNoProposerSettingsFound, filesystem.ErrNoProposerSettingsFound:
|
||||||
|
// Nothing to do.
|
||||||
|
default:
|
||||||
|
return errors.Wrap(err, "could not get proposer settings from source database")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attestations
|
// Attestations
|
||||||
|
@ -49,217 +49,224 @@ func TestDB_ConvertDatabase(t *testing.T) {
|
|||||||
defaultFeeRecipient := getFeeRecipientFromString(t, defaultFeeRecipientString)
|
defaultFeeRecipient := getFeeRecipientFromString(t, defaultFeeRecipientString)
|
||||||
customFeeRecipient := getFeeRecipientFromString(t, customFeeRecipientString)
|
customFeeRecipient := getFeeRecipientFromString(t, customFeeRecipientString)
|
||||||
|
|
||||||
for _, minimalToComplete := range []bool{false, true} {
|
for _, minimalToComplete := range [...]bool{false, true} {
|
||||||
t.Run(fmt.Sprintf("minimalToComplete=%v", minimalToComplete), func(t *testing.T) {
|
for _, withProposerSettings := range [...]bool{false, true} {
|
||||||
// Create signing root
|
t.Run(fmt.Sprintf("minimalToComplete=%v", minimalToComplete), func(t *testing.T) {
|
||||||
signingRoot := [fieldparams.RootLength]byte{}
|
// Create signing root
|
||||||
var signingRootBytes []byte
|
signingRoot := [fieldparams.RootLength]byte{}
|
||||||
if minimalToComplete {
|
var signingRootBytes []byte
|
||||||
signingRootBytes = signingRoot[:]
|
if minimalToComplete {
|
||||||
}
|
signingRootBytes = signingRoot[:]
|
||||||
|
}
|
||||||
|
|
||||||
// Create database directoriy path.
|
// Create database directoriy path.
|
||||||
datadir := t.TempDir()
|
datadir := t.TempDir()
|
||||||
|
|
||||||
// Run source DB preparation.
|
// Run source DB preparation.
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// Create the source database.
|
// Create the source database.
|
||||||
var (
|
var (
|
||||||
sourceDatabase, targetDatabase iface.ValidatorDB
|
sourceDatabase, targetDatabase iface.ValidatorDB
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if minimalToComplete {
|
if minimalToComplete {
|
||||||
sourceDatabase, err = filesystem.NewStore(datadir, &filesystem.Config{
|
sourceDatabase, err = filesystem.NewStore(datadir, &filesystem.Config{
|
||||||
PubKeys: [][fieldparams.BLSPubkeyLength]byte{pubkey1, pubkey2},
|
PubKeys: [][fieldparams.BLSPubkeyLength]byte{pubkey1, pubkey2},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
sourceDatabase, err = kv.NewKVStore(ctx, datadir, &kv.Config{
|
sourceDatabase, err = kv.NewKVStore(ctx, datadir, &kv.Config{
|
||||||
PubKeys: [][fieldparams.BLSPubkeyLength]byte{pubkey1, pubkey2},
|
PubKeys: [][fieldparams.BLSPubkeyLength]byte{pubkey1, pubkey2},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, err, "could not create source database")
|
require.NoError(t, err, "could not create source database")
|
||||||
|
|
||||||
// Save the genesis validator root.
|
// Save the genesis validator root.
|
||||||
expectedGenesisValidatorRoot := []byte("genesis-validator-root")
|
expectedGenesisValidatorRoot := []byte("genesis-validator-root")
|
||||||
err = sourceDatabase.SaveGenesisValidatorsRoot(ctx, expectedGenesisValidatorRoot)
|
err = sourceDatabase.SaveGenesisValidatorsRoot(ctx, expectedGenesisValidatorRoot)
|
||||||
require.NoError(t, err, "could not save genesis validator root")
|
require.NoError(t, err, "could not save genesis validator root")
|
||||||
|
|
||||||
// Save the graffiti file hash.
|
// Save the graffiti file hash.
|
||||||
// (Getting the graffiti ordered index will set the graffiti file hash)
|
// (Getting the graffiti ordered index will set the graffiti file hash)
|
||||||
expectedGraffitiFileHash := [32]byte{1}
|
expectedGraffitiFileHash := [32]byte{1}
|
||||||
_, err = sourceDatabase.GraffitiOrderedIndex(ctx, expectedGraffitiFileHash)
|
_, err = sourceDatabase.GraffitiOrderedIndex(ctx, expectedGraffitiFileHash)
|
||||||
require.NoError(t, err, "could not get graffiti ordered index")
|
require.NoError(t, err, "could not get graffiti ordered index")
|
||||||
|
|
||||||
// Save the graffiti ordered index.
|
// Save the graffiti ordered index.
|
||||||
expectedGraffitiOrderedIndex := uint64(1)
|
expectedGraffitiOrderedIndex := uint64(1)
|
||||||
err = sourceDatabase.SaveGraffitiOrderedIndex(ctx, expectedGraffitiOrderedIndex)
|
err = sourceDatabase.SaveGraffitiOrderedIndex(ctx, expectedGraffitiOrderedIndex)
|
||||||
require.NoError(t, err, "could not save graffiti ordered index")
|
require.NoError(t, err, "could not save graffiti ordered index")
|
||||||
|
|
||||||
// Save the proposer settings.
|
// Save the proposer settings.
|
||||||
var relays []string = nil
|
var relays []string = nil
|
||||||
|
expectedProposerSettings := &proposer.Settings{}
|
||||||
|
|
||||||
expectedProposerSettings := &proposer.Settings{
|
if withProposerSettings {
|
||||||
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{
|
expectedProposerSettings = &proposer.Settings{
|
||||||
pubkey1: {
|
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{
|
||||||
FeeRecipientConfig: &proposer.FeeRecipientConfig{
|
pubkey1: {
|
||||||
FeeRecipient: customFeeRecipient,
|
FeeRecipientConfig: &proposer.FeeRecipientConfig{
|
||||||
|
FeeRecipient: customFeeRecipient,
|
||||||
|
},
|
||||||
|
BuilderConfig: &proposer.BuilderConfig{
|
||||||
|
Enabled: true,
|
||||||
|
GasLimit: 42,
|
||||||
|
Relays: relays,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
BuilderConfig: &proposer.BuilderConfig{
|
DefaultConfig: &proposer.Option{
|
||||||
Enabled: true,
|
FeeRecipientConfig: &proposer.FeeRecipientConfig{
|
||||||
GasLimit: 42,
|
FeeRecipient: defaultFeeRecipient,
|
||||||
Relays: relays,
|
},
|
||||||
|
BuilderConfig: &proposer.BuilderConfig{
|
||||||
|
Enabled: false,
|
||||||
|
GasLimit: 43,
|
||||||
|
Relays: relays,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = sourceDatabase.SaveProposerSettings(ctx, expectedProposerSettings)
|
||||||
|
require.NoError(t, err, "could not save proposer settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save some attestations.
|
||||||
|
completeAttestations := []*ethpb.IndexedAttestation{
|
||||||
|
{
|
||||||
|
Data: ðpb.AttestationData{
|
||||||
|
Source: ðpb.Checkpoint{
|
||||||
|
Epoch: 1,
|
||||||
|
},
|
||||||
|
Target: ðpb.Checkpoint{
|
||||||
|
Epoch: 2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
DefaultConfig: &proposer.Option{
|
Data: ðpb.AttestationData{
|
||||||
FeeRecipientConfig: &proposer.FeeRecipientConfig{
|
Source: ðpb.Checkpoint{
|
||||||
FeeRecipient: defaultFeeRecipient,
|
Epoch: 2,
|
||||||
},
|
},
|
||||||
BuilderConfig: &proposer.BuilderConfig{
|
Target: ðpb.Checkpoint{
|
||||||
Enabled: false,
|
Epoch: 3,
|
||||||
GasLimit: 43,
|
},
|
||||||
Relays: relays,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sourceDatabase.SaveProposerSettings(ctx, expectedProposerSettings)
|
|
||||||
require.NoError(t, err, "could not save proposer settings")
|
|
||||||
|
|
||||||
// Save some attestations.
|
|
||||||
completeAttestations := []*ethpb.IndexedAttestation{
|
|
||||||
{
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
Source: ðpb.Checkpoint{
|
|
||||||
Epoch: 1,
|
|
||||||
},
|
|
||||||
Target: ðpb.Checkpoint{
|
|
||||||
Epoch: 2,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
{
|
|
||||||
Data: ðpb.AttestationData{
|
expectedAttestationRecords1 := []*common.AttestationRecord{
|
||||||
Source: ðpb.Checkpoint{
|
{
|
||||||
Epoch: 2,
|
PubKey: pubkey1,
|
||||||
},
|
Source: primitives.Epoch(2),
|
||||||
Target: ðpb.Checkpoint{
|
Target: primitives.Epoch(3),
|
||||||
Epoch: 3,
|
SigningRoot: signingRootBytes,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
}
|
|
||||||
|
|
||||||
expectedAttestationRecords1 := []*common.AttestationRecord{
|
expectedAttestationRecords2 := []*common.AttestationRecord{
|
||||||
{
|
{
|
||||||
PubKey: pubkey1,
|
PubKey: pubkey2,
|
||||||
Source: primitives.Epoch(2),
|
Source: primitives.Epoch(2),
|
||||||
Target: primitives.Epoch(3),
|
Target: primitives.Epoch(3),
|
||||||
SigningRoot: signingRootBytes,
|
SigningRoot: signingRootBytes,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedAttestationRecords2 := []*common.AttestationRecord{
|
err = sourceDatabase.SaveAttestationsForPubKey(ctx, pubkey1, [][]byte{{1}, {2}}, completeAttestations)
|
||||||
{
|
require.NoError(t, err, "could not save attestations")
|
||||||
PubKey: pubkey2,
|
|
||||||
Source: primitives.Epoch(2),
|
|
||||||
Target: primitives.Epoch(3),
|
|
||||||
SigningRoot: signingRootBytes,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sourceDatabase.SaveAttestationsForPubKey(ctx, pubkey1, [][]byte{{1}, {2}}, completeAttestations)
|
err = sourceDatabase.SaveAttestationsForPubKey(ctx, pubkey2, [][]byte{{1}, {2}}, completeAttestations)
|
||||||
require.NoError(t, err, "could not save attestations")
|
require.NoError(t, err, "could not save attestations")
|
||||||
|
|
||||||
err = sourceDatabase.SaveAttestationsForPubKey(ctx, pubkey2, [][]byte{{1}, {2}}, completeAttestations)
|
// Save some block proposals.
|
||||||
require.NoError(t, err, "could not save attestations")
|
err = sourceDatabase.SaveProposalHistoryForSlot(ctx, pubkey1, 42, []byte{})
|
||||||
|
require.NoError(t, err, "could not save block proposal")
|
||||||
|
|
||||||
// Save some block proposals.
|
err = sourceDatabase.SaveProposalHistoryForSlot(ctx, pubkey1, 43, []byte{})
|
||||||
err = sourceDatabase.SaveProposalHistoryForSlot(ctx, pubkey1, 42, []byte{})
|
require.NoError(t, err, "could not save block proposal")
|
||||||
require.NoError(t, err, "could not save block proposal")
|
|
||||||
|
|
||||||
err = sourceDatabase.SaveProposalHistoryForSlot(ctx, pubkey1, 43, []byte{})
|
expectedProposals := []*common.Proposal{
|
||||||
require.NoError(t, err, "could not save block proposal")
|
{
|
||||||
|
Slot: 43,
|
||||||
|
SigningRoot: signingRootBytes,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
expectedProposals := []*common.Proposal{
|
// Close the source database.
|
||||||
{
|
err = sourceDatabase.Close()
|
||||||
Slot: 43,
|
require.NoError(t, err, "could not close source database")
|
||||||
SigningRoot: signingRootBytes,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the source database.
|
// Source to target DB conversion.
|
||||||
err = sourceDatabase.Close()
|
// -------------------------------
|
||||||
require.NoError(t, err, "could not close source database")
|
err = ConvertDatabase(ctx, datadir, datadir, minimalToComplete)
|
||||||
|
require.NoError(t, err, "could not convert source to target database")
|
||||||
|
|
||||||
// Source to target DB conversion.
|
// Check the target database.
|
||||||
// ----------------------------------------
|
// --------------------------
|
||||||
err = ConvertDatabase(ctx, datadir, datadir, minimalToComplete)
|
if minimalToComplete {
|
||||||
require.NoError(t, err, "could not convert source to target database")
|
targetDatabase, err = kv.NewKVStore(ctx, datadir, nil)
|
||||||
|
} else {
|
||||||
|
targetDatabase, err = filesystem.NewStore(datadir, nil)
|
||||||
|
}
|
||||||
|
require.NoError(t, err, "could not get minimal database")
|
||||||
|
|
||||||
// Check the target database.
|
// Check the genesis validator root.
|
||||||
// --------------------------
|
actualGenesisValidatoRoot, err := targetDatabase.GenesisValidatorsRoot(ctx)
|
||||||
if minimalToComplete {
|
require.NoError(t, err, "could not get genesis validator root from target database")
|
||||||
targetDatabase, err = kv.NewKVStore(ctx, datadir, nil)
|
require.DeepSSZEqual(t, expectedGenesisValidatorRoot, actualGenesisValidatoRoot, "genesis validator root should match")
|
||||||
} else {
|
|
||||||
targetDatabase, err = filesystem.NewStore(datadir, nil)
|
|
||||||
}
|
|
||||||
require.NoError(t, err, "could not get minimal database")
|
|
||||||
|
|
||||||
// Check the genesis validator root.
|
// Check the graffiti file hash.
|
||||||
actualGenesisValidatoRoot, err := targetDatabase.GenesisValidatorsRoot(ctx)
|
actualGraffitiFileHash, exists, err := targetDatabase.GraffitiFileHash()
|
||||||
require.NoError(t, err, "could not get genesis validator root from target database")
|
require.NoError(t, err, "could not get graffiti file hash from target database")
|
||||||
require.DeepSSZEqual(t, expectedGenesisValidatorRoot, actualGenesisValidatoRoot, "genesis validator root should match")
|
require.Equal(t, true, exists, "graffiti file hash should exist")
|
||||||
|
require.Equal(t, expectedGraffitiFileHash, actualGraffitiFileHash, "graffiti file hash should match")
|
||||||
|
|
||||||
// Check the graffiti file hash.
|
// Check the graffiti ordered index.
|
||||||
actualGraffitiFileHash, exists, err := targetDatabase.GraffitiFileHash()
|
actualGraffitiOrderedIndex, err := targetDatabase.GraffitiOrderedIndex(ctx, expectedGraffitiFileHash)
|
||||||
require.NoError(t, err, "could not get graffiti file hash from target database")
|
require.NoError(t, err, "could not get graffiti ordered index from target database")
|
||||||
require.Equal(t, true, exists, "graffiti file hash should exist")
|
require.Equal(t, expectedGraffitiOrderedIndex, actualGraffitiOrderedIndex, "graffiti ordered index should match")
|
||||||
require.Equal(t, expectedGraffitiFileHash, actualGraffitiFileHash, "graffiti file hash should match")
|
|
||||||
|
|
||||||
// Check the graffiti ordered index.
|
if withProposerSettings {
|
||||||
actualGraffitiOrderedIndex, err := targetDatabase.GraffitiOrderedIndex(ctx, expectedGraffitiFileHash)
|
// Check the proposer settings.
|
||||||
require.NoError(t, err, "could not get graffiti ordered index from target database")
|
actualProposerSettings, err := targetDatabase.ProposerSettings(ctx)
|
||||||
require.Equal(t, expectedGraffitiOrderedIndex, actualGraffitiOrderedIndex, "graffiti ordered index should match")
|
require.NoError(t, err, "could not get proposer settings from target database")
|
||||||
|
require.DeepEqual(t, expectedProposerSettings, actualProposerSettings, "proposer settings should match")
|
||||||
|
}
|
||||||
|
|
||||||
// Check the proposer settings.
|
// Check the attestations.
|
||||||
actualProposerSettings, err := targetDatabase.ProposerSettings(ctx)
|
actualAttestationRecords, err := targetDatabase.AttestationHistoryForPubKey(ctx, pubkey1)
|
||||||
require.NoError(t, err, "could not get proposer settings from target database")
|
require.NoError(t, err, "could not get attestations from target database")
|
||||||
require.DeepEqual(t, expectedProposerSettings, actualProposerSettings, "proposer settings should match")
|
require.DeepEqual(t, expectedAttestationRecords1, actualAttestationRecords, "attestations should match")
|
||||||
|
|
||||||
// Check the attestations.
|
actualAttestationRecords, err = targetDatabase.AttestationHistoryForPubKey(ctx, pubkey2)
|
||||||
actualAttestationRecords, err := targetDatabase.AttestationHistoryForPubKey(ctx, pubkey1)
|
require.NoError(t, err, "could not get attestations from target database")
|
||||||
require.NoError(t, err, "could not get attestations from target database")
|
require.DeepEqual(t, expectedAttestationRecords2, actualAttestationRecords, "attestations should match")
|
||||||
require.DeepEqual(t, expectedAttestationRecords1, actualAttestationRecords, "attestations should match")
|
|
||||||
|
|
||||||
actualAttestationRecords, err = targetDatabase.AttestationHistoryForPubKey(ctx, pubkey2)
|
// Check the block proposals.
|
||||||
require.NoError(t, err, "could not get attestations from target database")
|
actualProposals, err := targetDatabase.ProposalHistoryForPubKey(ctx, pubkey1)
|
||||||
require.DeepEqual(t, expectedAttestationRecords2, actualAttestationRecords, "attestations should match")
|
require.NoError(t, err, "could not get block proposals from target database")
|
||||||
|
require.DeepEqual(t, expectedProposals, actualProposals, "block proposals should match")
|
||||||
|
|
||||||
// Check the block proposals.
|
// Close the target database.
|
||||||
actualProposals, err := targetDatabase.ProposalHistoryForPubKey(ctx, pubkey1)
|
err = targetDatabase.Close()
|
||||||
require.NoError(t, err, "could not get block proposals from target database")
|
require.NoError(t, err, "could not close target database")
|
||||||
require.DeepEqual(t, expectedProposals, actualProposals, "block proposals should match")
|
|
||||||
|
|
||||||
// Close the target database.
|
// Check the source database does not exist anymore.
|
||||||
err = targetDatabase.Close()
|
var existing bool
|
||||||
require.NoError(t, err, "could not close target database")
|
|
||||||
|
|
||||||
// Check the source database does not exist anymore.
|
if minimalToComplete {
|
||||||
var existing bool
|
databasePath := filepath.Join(datadir, filesystem.DatabaseDirName)
|
||||||
|
existing, err = file.Exists(databasePath, file.Directory)
|
||||||
|
} else {
|
||||||
|
databasePath := filepath.Join(datadir, kv.ProtectionDbFileName)
|
||||||
|
existing, err = file.Exists(databasePath, file.Regular)
|
||||||
|
}
|
||||||
|
|
||||||
if minimalToComplete {
|
require.NoError(t, err, "could not check if source database exists")
|
||||||
databasePath := filepath.Join(datadir, filesystem.DatabaseDirName)
|
require.Equal(t, false, existing, "source database should not exist")
|
||||||
existing, err = file.Exists(databasePath, file.Directory)
|
})
|
||||||
} else {
|
}
|
||||||
databasePath := filepath.Join(datadir, kv.ProtectionDbFileName)
|
|
||||||
existing, err = file.Exists(databasePath, file.Regular)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, err, "could not check if source database exists")
|
|
||||||
require.Equal(t, false, existing, "source database should not exist")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user