From 55775ffdf31617f2bd49b75ed6e6b56a133bdfd2 Mon Sep 17 00:00:00 2001 From: Anton Korpusenko Date: Mon, 8 Apr 2024 18:21:59 +0300 Subject: [PATCH 1/2] Test coverage improvement of EKM package (#1337) * improved codecoverage of ekm package * minor fixes --- ekm/signer_key_manager_test.go | 330 ++++++++++++++++++++++++++++++++- ekm/signer_storage_test.go | 26 +++ 2 files changed, 354 insertions(+), 2 deletions(-) diff --git a/ekm/signer_key_manager_test.go b/ekm/signer_key_manager_test.go index 5089b912bd..0eb55e378c 100644 --- a/ekm/signer_key_manager_test.go +++ b/ekm/signer_key_manager_test.go @@ -2,21 +2,24 @@ package ekm import ( "encoding/hex" - "testing" - + eth2apiv1 "github.com/attestantio/go-eth2-client/api/v1" "github.com/attestantio/go-eth2-client/spec/altair" "github.com/attestantio/go-eth2-client/spec/bellatrix" "github.com/attestantio/go-eth2-client/spec/capella" + "github.com/attestantio/go-eth2-client/spec/deneb" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/bloxapp/eth2-key-manager/core" "github.com/bloxapp/eth2-key-manager/wallets/hd" specqbft "github.com/bloxapp/ssv-spec/qbft" spectypes "github.com/bloxapp/ssv-spec/types" "github.com/herumi/bls-eth-go-binary/bls" + "github.com/holiman/uint256" "github.com/pkg/errors" "github.com/prysmaticlabs/go-bitfield" "github.com/stretchr/testify/require" "go.uber.org/zap" + "testing" + "time" "github.com/bloxapp/ssv/logging" "github.com/bloxapp/ssv/networkconfig" @@ -251,6 +254,9 @@ func TestSlashing(t *testing.T) { } t.Run("sign once", func(t *testing.T) { + err := km.(*ethKeyManagerSigner).IsAttestationSlashable(sk1.GetPublicKey().Serialize(), attestationData) + require.NoError(t, err) + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject(attestationData, phase0.Domain{}, sk1.GetPublicKey().Serialize(), spectypes.DomainAttester) require.NoError(t, err) require.NotNil(t, sig) @@ -260,9 +266,14 @@ func TestSlashing(t *testing.T) { _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject(attestationData, phase0.Domain{}, sk1.GetPublicKey().Serialize(), spectypes.DomainAttester) require.EqualError(t, err, "slashable attestation (HighestAttestationVote), not signing") require.Equal(t, [32]byte{}, sig) + + err = km.(*ethKeyManagerSigner).IsAttestationSlashable(sk1.GetPublicKey().Serialize(), attestationData) + require.EqualError(t, err, "slashable attestation (HighestAttestationVote), not signing") }) t.Run("sign once", func(t *testing.T) { + err := km.(*ethKeyManagerSigner).IsBeaconBlockSlashable(sk1.GetPublicKey().Serialize(), beaconBlock.Slot) + require.NoError(t, err) _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject(beaconBlock, phase0.Domain{}, sk1.GetPublicKey().Serialize(), spectypes.DomainProposer) require.NoError(t, err) require.NotNil(t, sig) @@ -272,6 +283,9 @@ func TestSlashing(t *testing.T) { _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject(beaconBlock, phase0.Domain{}, sk1.GetPublicKey().Serialize(), spectypes.DomainProposer) require.EqualError(t, err, "slashable proposal (HighestProposalVote), not signing") require.Equal(t, [32]byte{}, sig) + + err = km.(*ethKeyManagerSigner).IsBeaconBlockSlashable(sk1.GetPublicKey().Serialize(), beaconBlock.Slot) + require.EqualError(t, err, "slashable proposal (HighestProposalVote), not signing") }) t.Run("slashable sign after duplicate AddShare, fail", func(t *testing.T) { require.NoError(t, km.AddShare(sk1)) @@ -281,6 +295,284 @@ func TestSlashing(t *testing.T) { }) } +func TestSignBeaconObject(t *testing.T) { + km := testKeyManager(t, nil) + + sk1 := &bls.SecretKey{} + require.NoError(t, sk1.SetHexString(sk1Str)) + require.NoError(t, km.AddShare(sk1)) + + currentSlot := km.(*ethKeyManagerSigner).storage.Network().EstimatedCurrentSlot() + highestProposal := currentSlot + minSPProposalSlotGap + 1 + + t.Run("Sign Deneb block", func(t *testing.T) { + var beaconBlock = &deneb.BeaconBlock{ + Slot: highestProposal, + ProposerIndex: 0, + ParentRoot: phase0.Root{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + StateRoot: phase0.Root{ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + }, + Body: &deneb.BeaconBlockBody{ + RANDAOReveal: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + ETH1Data: &phase0.ETH1Data{ + DepositRoot: phase0.Root{ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + }, + DepositCount: 0, + BlockHash: []byte{ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + }, + }, + Graffiti: [32]byte{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + ProposerSlashings: []*phase0.ProposerSlashing{}, + AttesterSlashings: []*phase0.AttesterSlashing{}, + Attestations: []*phase0.Attestation{}, + Deposits: []*phase0.Deposit{}, + VoluntaryExits: []*phase0.SignedVoluntaryExit{}, + SyncAggregate: &altair.SyncAggregate{ + SyncCommitteeBits: bitfield.Bitvector512{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + SyncCommitteeSignature: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + }, + ExecutionPayload: &deneb.ExecutionPayload{ + ParentHash: phase0.Hash32{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + FeeRecipient: bellatrix.ExecutionAddress{}, + StateRoot: [32]byte{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + ReceiptsRoot: [32]byte{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + LogsBloom: [256]byte{}, + PrevRandao: [32]byte{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + BlockNumber: 0, + GasLimit: 0, + GasUsed: 0, + Timestamp: 0, + ExtraData: nil, + BaseFeePerGas: &uint256.Int{1, 2, 3, 5}, + BlockHash: phase0.Hash32{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + Transactions: []bellatrix.Transaction{}, + Withdrawals: []*capella.Withdrawal{}, + }, + }, + } + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + beaconBlock, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainProposer, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainVoluntaryExit", func(t *testing.T) { + var voluntaryExit = &phase0.VoluntaryExit{ + Epoch: 1, + ValidatorIndex: 1, + } + + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + voluntaryExit, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainVoluntaryExit, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainAggregateAndProof", func(t *testing.T) { + var voluntaryExit = &phase0.AggregateAndProof{ + AggregatorIndex: 1, + Aggregate: &phase0.Attestation{ + AggregationBits: bitfield.Bitlist{0, 1, 2, 3, 5, 6, 7, 8, 9, 10}, + Data: &phase0.AttestationData{ + Slot: currentSlot, + }, + Signature: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + }, + SelectionProof: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + } + + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + voluntaryExit, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainAggregateAndProof, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainSelectionProof", func(t *testing.T) { + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + spectypes.SSZUint64(1), + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainSelectionProof, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainRandao", func(t *testing.T) { + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + spectypes.SSZUint64(1), + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainRandao, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainSyncCommittee", func(t *testing.T) { + data := spectypes.SSZBytes{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + } + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + data, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainSyncCommittee, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainSyncCommitteeSelectionProof", func(t *testing.T) { + data := &altair.SyncAggregatorSelectionData{ + Slot: currentSlot, + SubcommitteeIndex: 1, + } + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + data, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainSyncCommitteeSelectionProof, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainContributionAndProof", func(t *testing.T) { + data := &altair.ContributionAndProof{ + AggregatorIndex: 1, + Contribution: &altair.SyncCommitteeContribution{ + Slot: currentSlot, + BeaconBlockRoot: [32]byte{1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2}, + SubcommitteeIndex: 1, + AggregationBits: bitfield.Bitvector128{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0xa, 0xb, 0xc, 0xd, 0xe}, + Signature: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + }, + SelectionProof: phase0.BLSSignature{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + } + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + data, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainContributionAndProof, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) + t.Run("DomainApplicationBuilder", func(t *testing.T) { + pk := &bls.SecretKey{} + pk.SetByCSPRNG() + + data := ð2apiv1.ValidatorRegistration{ + GasLimit: 123, + FeeRecipient: bellatrix.ExecutionAddress{}, + Timestamp: time.Unix(1231006505, 0), + Pubkey: phase0.BLSPubKey{ + 0x0a, 0x0d, 0x0e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x0e, 0x0e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x0f, 0x0e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + } + _, sig, err := km.(*ethKeyManagerSigner).SignBeaconObject( + data, + phase0.Domain{}, + sk1.GetPublicKey().Serialize(), + spectypes.DomainApplicationBuilder, + ) + require.NoError(t, err) + require.NotNil(t, sig) + require.NotEqual(t, [32]byte{}, sig) + }) +} + func TestSlashing_Attestation(t *testing.T) { km := testKeyManager(t, nil) @@ -453,3 +745,37 @@ func TestSignRoot(t *testing.T) { // require.True(t, res) }) } + +func TestRemoveShare(t *testing.T) { + require.NoError(t, bls.Init(bls.BLS12_381)) + + t.Run("key exists", func(t *testing.T) { + km := testKeyManager(t, nil) + pk := &bls.SecretKey{} + // generate random key + pk.SetByCSPRNG() + err := km.AddShare(pk) + require.NoError(t, err) + err = km.RemoveShare(pk.GetPublicKey().GetHexString()) + require.NoError(t, err) + }) + + t.Run("key doesn't exist", func(t *testing.T) { + km := testKeyManager(t, nil) + + pk := &bls.SecretKey{} + pk.SetByCSPRNG() + + err := km.RemoveShare(pk.GetPublicKey().GetHexString()) + require.NoError(t, err) + }) +} + +func TestEkmListAccounts(t *testing.T) { + require.NoError(t, bls.Init(bls.BLS12_381)) + + km := testKeyManager(t, nil) + accounts, err := km.(*ethKeyManagerSigner).ListAccounts() + require.NoError(t, err) + require.Equal(t, 2, len(accounts)) +} diff --git a/ekm/signer_storage_test.go b/ekm/signer_storage_test.go index abdfd485e1..d608cdf875 100644 --- a/ekm/signer_storage_test.go +++ b/ekm/signer_storage_test.go @@ -520,3 +520,29 @@ func TestRemovingHighestProposal(t *testing.T) { }) } } + +func TestListAccounts(t *testing.T) { + _, signerStorage, done := testWallet(t) + defer done() + + accounts, err := signerStorage.ListAccounts() + + require.NoError(t, err) + require.Equal(t, 1, len(accounts)) +} + +func TestName(t *testing.T) { + _, signerStorage, done := testWallet(t) + defer done() + + name := signerStorage.Name() + require.Equal(t, "SSV Storage", name) +} + +func TestDropRegistryData(t *testing.T) { + _, signerStorage, done := testWallet(t) + defer done() + + err := signerStorage.DropRegistryData() + require.NoError(t, err) +} From 4966dceec8a0a2d36cef3bc8a7b2edcd9b890fcd Mon Sep 17 00:00:00 2001 From: Anton Korpusenko Date: Mon, 8 Apr 2024 18:29:57 +0300 Subject: [PATCH 2/2] Added sync.once to prevent data race in rsa keys linux build impl (#1364) * added mutex to prevent data race in rsa keys linux build impl * replaced sync.Mutex with sync.Once * test deploy * revert deploy --- operator/keys/rsa_linux.go | 34 +++++++++++++-------------------- operator/keys/rsa_linux_test.go | 13 ++++++------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/operator/keys/rsa_linux.go b/operator/keys/rsa_linux.go index 2f736396d5..7533171fb1 100644 --- a/operator/keys/rsa_linux.go +++ b/operator/keys/rsa_linux.go @@ -7,6 +7,7 @@ import ( "crypto/rsa" "crypto/sha256" "math/big" + "sync" "github.com/microsoft/go-crypto-openssl/openssl" "github.com/microsoft/go-crypto-openssl/openssl/bbig/bridge" @@ -15,11 +16,13 @@ import ( type privateKey struct { privKey *rsa.PrivateKey cachedPrivKey *openssl.PrivateKeyRSA + once sync.Once } type publicKey struct { pubKey *rsa.PublicKey cachedPubkey *openssl.PublicKeyRSA + once sync.Once } func init() { @@ -51,16 +54,11 @@ func rsaPublicKeyToOpenSSL(pub *rsa.PublicKey) (*openssl.PublicKeyRSA, error) { } func checkCachePrivkey(priv *privateKey) (*openssl.PrivateKeyRSA, error) { - if priv.cachedPrivKey != nil { - return priv.cachedPrivKey, nil - } - opriv, err := rsaPrivateKeyToOpenSSL(priv.privKey) - if err != nil { - return nil, err - } - priv.cachedPrivKey = opriv - - return opriv, nil + var err error + priv.once.Do(func() { + priv.cachedPrivKey, err = rsaPrivateKeyToOpenSSL(priv.privKey) + }) + return priv.cachedPrivKey, err } func SignRSA(priv *privateKey, data []byte) ([]byte, error) { @@ -72,17 +70,11 @@ func SignRSA(priv *privateKey, data []byte) ([]byte, error) { } func checkCachePubkey(pub *publicKey) (*openssl.PublicKeyRSA, error) { - if pub.cachedPubkey != nil { - return pub.cachedPubkey, nil - } - - opub, err := rsaPublicKeyToOpenSSL(pub.pubKey) - if err != nil { - return nil, err - } - pub.cachedPubkey = opub - - return opub, nil + var err error + pub.once.Do(func() { + pub.cachedPubkey, err = rsaPublicKeyToOpenSSL(pub.pubKey) + }) + return pub.cachedPubkey, err } func EncryptRSA(pub *publicKey, data []byte) ([]byte, error) { diff --git a/operator/keys/rsa_linux_test.go b/operator/keys/rsa_linux_test.go index e53d875fdf..158fdce314 100644 --- a/operator/keys/rsa_linux_test.go +++ b/operator/keys/rsa_linux_test.go @@ -6,9 +6,8 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha256" - "github.com/stretchr/testify/require" - + "sync" "testing" ) @@ -21,7 +20,7 @@ func Test_VerifyRegularSigWithOpenSSL(t *testing.T) { sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:]) require.NoError(t, err) - pk := &privateKey{key, nil} + pk := &privateKey{key, nil, sync.Once{}} pub := pk.Public().(*publicKey) require.NoError(t, VerifyRSA(pub, msg, sig)) @@ -41,7 +40,7 @@ func Test_VerifyOpenSSLWithOpenSSL(t *testing.T) { key, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) msg := []byte("hello") - priv := &privateKey{key, nil} + priv := &privateKey{key, nil, sync.Once{}} sig, err := priv.Sign(msg) require.NoError(t, err) @@ -61,14 +60,14 @@ func Test_ConversionError(t *testing.T) { key.D = nil msg := []byte("hello") - priv := &privateKey{key, nil} + priv := &privateKey{key, nil, sync.Once{}} _, err = priv.Sign(msg) require.Error(t, err) key2, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) - priv2 := &privateKey{key2, nil} + priv2 := &privateKey{key2, nil, sync.Once{}} sig, err := priv2.Sign(msg) require.NoError(t, err) pub := priv2.Public().(*publicKey) @@ -81,7 +80,7 @@ func Test_Caches(t *testing.T) { key, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) msg := []byte("hello") - priv := &privateKey{key, nil} + priv := &privateKey{key, nil, sync.Once{}} sig, err := priv.Sign(msg) require.NoError(t, err)