mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
270 lines
8.0 KiB
Go
270 lines
8.0 KiB
Go
package slasher
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
|
dbtest "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing"
|
|
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
|
|
slashingsmock "github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/slashings/mock"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stategen"
|
|
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
|
"github.com/prysmaticlabs/prysm/v5/config/params"
|
|
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
|
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
|
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
|
)
|
|
|
|
func TestService_processAttesterSlashings(t *testing.T) {
|
|
ctx := context.Background()
|
|
slasherDB := dbtest.SetupSlasherDB(t)
|
|
beaconDB := dbtest.SetupDB(t)
|
|
|
|
beaconState, err := util.NewBeaconState()
|
|
require.NoError(t, err)
|
|
|
|
privKey, err := bls.RandKey()
|
|
require.NoError(t, err)
|
|
validators := make([]*ethpb.Validator, 1)
|
|
validators[0] = ðpb.Validator{
|
|
PublicKey: privKey.PublicKey().Marshal(),
|
|
WithdrawalCredentials: make([]byte, 32),
|
|
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
|
}
|
|
err = beaconState.SetValidators(validators)
|
|
require.NoError(t, err)
|
|
|
|
mockChain := &mock.ChainService{
|
|
State: beaconState,
|
|
}
|
|
s := &Service{
|
|
serviceCfg: &ServiceConfig{
|
|
Database: slasherDB,
|
|
AttestationStateFetcher: mockChain,
|
|
StateGen: stategen.New(beaconDB, doublylinkedtree.New()),
|
|
SlashingPoolInserter: &slashingsmock.PoolMock{},
|
|
HeadStateFetcher: mockChain,
|
|
},
|
|
}
|
|
|
|
firstAtt := util.HydrateIndexedAttestation(ðpb.IndexedAttestation{
|
|
AttestingIndices: []uint64{0},
|
|
})
|
|
secondAtt := util.HydrateIndexedAttestation(ðpb.IndexedAttestation{
|
|
AttestingIndices: []uint64{0},
|
|
})
|
|
|
|
domain, err := signing.Domain(
|
|
beaconState.Fork(),
|
|
0,
|
|
params.BeaconConfig().DomainBeaconAttester,
|
|
beaconState.GenesisValidatorsRoot(),
|
|
)
|
|
require.NoError(t, err)
|
|
signingRoot, err := signing.ComputeSigningRoot(firstAtt.Data, domain)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("first_att_valid_sig_second_invalid", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use valid signature for the first att, but bad one for the second.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstAtt.Signature = signature.Marshal()
|
|
secondAtt.Signature = make([]byte, 96)
|
|
|
|
slashing := ðpb.AttesterSlashing{
|
|
Attestation_1: firstAtt,
|
|
Attestation_2: secondAtt,
|
|
}
|
|
|
|
root, err := slashing.HashTreeRoot()
|
|
require.NoError(tt, err, "failed to hash tree root")
|
|
|
|
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
|
root: slashing,
|
|
}
|
|
|
|
_, err = s.processAttesterSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsContain(tt, hook, "Invalid signature")
|
|
})
|
|
|
|
t.Run("first_att_invalid_sig_second_valid", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use invalid signature for the first att, but valid for the second.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstAtt.Signature = make([]byte, 96)
|
|
secondAtt.Signature = signature.Marshal()
|
|
|
|
slashing := ðpb.AttesterSlashing{
|
|
Attestation_1: firstAtt,
|
|
Attestation_2: secondAtt,
|
|
}
|
|
|
|
root, err := slashing.HashTreeRoot()
|
|
require.NoError(tt, err, "failed to hash tree root")
|
|
|
|
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
|
root: slashing,
|
|
}
|
|
|
|
_, err = s.processAttesterSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsContain(tt, hook, "Invalid signature")
|
|
})
|
|
|
|
t.Run("both_valid_att_signatures", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use valid signatures.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstAtt.Signature = signature.Marshal()
|
|
secondAtt.Signature = signature.Marshal()
|
|
|
|
slashing := ðpb.AttesterSlashing{
|
|
Attestation_1: firstAtt,
|
|
Attestation_2: secondAtt,
|
|
}
|
|
|
|
root, err := slashing.HashTreeRoot()
|
|
require.NoError(tt, err, "failed to hash tree root")
|
|
|
|
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
|
root: slashing,
|
|
}
|
|
|
|
_, err = s.processAttesterSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsDoNotContain(tt, hook, "Invalid signature")
|
|
})
|
|
}
|
|
|
|
func TestService_processProposerSlashings(t *testing.T) {
|
|
ctx := context.Background()
|
|
slasherDB := dbtest.SetupSlasherDB(t)
|
|
beaconDB := dbtest.SetupDB(t)
|
|
|
|
beaconState, err := util.NewBeaconState()
|
|
require.NoError(t, err)
|
|
|
|
privKey, err := bls.RandKey()
|
|
require.NoError(t, err)
|
|
validators := make([]*ethpb.Validator, 1)
|
|
validators[0] = ðpb.Validator{
|
|
PublicKey: privKey.PublicKey().Marshal(),
|
|
WithdrawalCredentials: make([]byte, 32),
|
|
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
|
}
|
|
err = beaconState.SetValidators(validators)
|
|
require.NoError(t, err)
|
|
|
|
mockChain := &mock.ChainService{
|
|
State: beaconState,
|
|
}
|
|
s := &Service{
|
|
serviceCfg: &ServiceConfig{
|
|
Database: slasherDB,
|
|
AttestationStateFetcher: mockChain,
|
|
StateGen: stategen.New(beaconDB, doublylinkedtree.New()),
|
|
SlashingPoolInserter: &slashingsmock.PoolMock{},
|
|
HeadStateFetcher: mockChain,
|
|
},
|
|
}
|
|
|
|
parentRoot := bytesutil.ToBytes32([]byte("parent"))
|
|
err = s.serviceCfg.StateGen.SaveState(ctx, parentRoot, beaconState)
|
|
require.NoError(t, err)
|
|
|
|
firstBlockHeader := util.HydrateSignedBeaconHeader(ðpb.SignedBeaconBlockHeader{
|
|
Header: ðpb.BeaconBlockHeader{
|
|
Slot: 0,
|
|
ProposerIndex: 0,
|
|
ParentRoot: parentRoot[:],
|
|
},
|
|
})
|
|
secondBlockHeader := util.HydrateSignedBeaconHeader(ðpb.SignedBeaconBlockHeader{
|
|
Header: ðpb.BeaconBlockHeader{
|
|
Slot: 0,
|
|
ProposerIndex: 0,
|
|
ParentRoot: parentRoot[:],
|
|
},
|
|
})
|
|
|
|
domain, err := signing.Domain(
|
|
beaconState.Fork(),
|
|
0,
|
|
params.BeaconConfig().DomainBeaconProposer,
|
|
beaconState.GenesisValidatorsRoot(),
|
|
)
|
|
require.NoError(t, err)
|
|
htr, err := firstBlockHeader.Header.HashTreeRoot()
|
|
require.NoError(t, err)
|
|
container := ðpb.SigningData{
|
|
ObjectRoot: htr[:],
|
|
Domain: domain,
|
|
}
|
|
require.NoError(t, err)
|
|
signingRoot, err := container.HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
t.Run("first_header_valid_sig_second_invalid", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use valid signature for the first header, but bad one for the second.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstBlockHeader.Signature = signature.Marshal()
|
|
secondBlockHeader.Signature = make([]byte, 96)
|
|
|
|
slashings := []*ethpb.ProposerSlashing{
|
|
{
|
|
Header_1: firstBlockHeader,
|
|
Header_2: secondBlockHeader,
|
|
},
|
|
}
|
|
|
|
err = s.processProposerSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsContain(tt, hook, "Invalid signature")
|
|
})
|
|
|
|
t.Run("first_header_invalid_sig_second_valid", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use invalid signature for the first header, but valid for the second.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstBlockHeader.Signature = make([]byte, 96)
|
|
secondBlockHeader.Signature = signature.Marshal()
|
|
|
|
slashings := []*ethpb.ProposerSlashing{
|
|
{
|
|
Header_1: firstBlockHeader,
|
|
Header_2: secondBlockHeader,
|
|
},
|
|
}
|
|
|
|
err = s.processProposerSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsContain(tt, hook, "Invalid signature")
|
|
})
|
|
|
|
t.Run("both_valid_header_signatures", func(tt *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Use valid signatures.
|
|
signature := privKey.Sign(signingRoot[:])
|
|
firstBlockHeader.Signature = signature.Marshal()
|
|
secondBlockHeader.Signature = signature.Marshal()
|
|
|
|
slashings := []*ethpb.ProposerSlashing{
|
|
{
|
|
Header_1: firstBlockHeader,
|
|
Header_2: secondBlockHeader,
|
|
},
|
|
}
|
|
|
|
err = s.processProposerSlashings(ctx, slashings)
|
|
require.NoError(tt, err)
|
|
require.LogsDoNotContain(tt, hook, "Invalid signature")
|
|
})
|
|
}
|