Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peer authentication sender factory #4414

Merged
merged 8 commits into from
Sep 1, 2022
1 change: 1 addition & 0 deletions cmd/node/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@
MaxDurationPeerUnresponsiveInSec = 900 # 15min
HideInactiveValidatorIntervalInSec = 3600 # 1h
HardforkTimeBetweenSendsInSec = 60 # 1min
PeerAuthenticationTimeBetweenChecksInSec = 6 # 6sec
[HeartbeatV2.PeerAuthenticationPool]
DefaultSpanInSec = 3600 # 1h
CacheExpiryInSec = 3600 # 1h
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ type HeartbeatV2Config struct {
PeerAuthenticationPool PeerAuthenticationPoolConfig
HeartbeatPool CacheConfig
HardforkTimeBetweenSendsInSec int64
PeerAuthenticationTimeBetweenChecksInSec int64
}

// PeerAuthenticationPoolConfig will hold the configuration for peer authentication pool
Expand Down
3 changes: 3 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,6 @@ var ErrDBIsClosed = errors.New("DB is closed")

// ErrNilEnableEpochsHandler signals that a nil enable epochs handler was provided
var ErrNilEnableEpochsHandler = errors.New("nil enable epochs handler")

// ErrNilKeysHolder signals that a nil keys holder has been provided
var ErrNilKeysHolder = errors.New("nil keys holder")
28 changes: 27 additions & 1 deletion factory/cryptoComponents.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,26 @@ import (
"github.com/ElrondNetwork/elrond-go/errors"
"github.com/ElrondNetwork/elrond-go/factory/peerSignatureHandler"
"github.com/ElrondNetwork/elrond-go/genesis/process/disabled"
"github.com/ElrondNetwork/elrond-go/heartbeat"
"github.com/ElrondNetwork/elrond-go/keysManagement"
p2pCrypto "github.com/ElrondNetwork/elrond-go/p2p/crypto"
storageFactory "github.com/ElrondNetwork/elrond-go/storage/factory"
"github.com/ElrondNetwork/elrond-go/storage/storageUnit"
"github.com/ElrondNetwork/elrond-go/vm"
systemVM "github.com/ElrondNetwork/elrond-go/vm/process"
)

const disabledSigChecking = "disabled"
const (
disabledSigChecking = "disabled"
mainMachineRedundancyLevel = 0
)

// CryptoComponentsFactoryArgs holds the arguments needed for creating crypto components
type CryptoComponentsFactoryArgs struct {
ValidatorKeyPemFileName string
SkIndex int
Config config.Config
PrefsConfig config.Preferences
CoreComponentsHolder CoreComponentsHolder
KeyLoader KeyLoaderHandler
ActivateBLSPubKeyMessageVerification bool
Expand All @@ -51,6 +58,7 @@ type cryptoComponentsFactory struct {
validatorKeyPemFileName string
skIndex int
config config.Config
prefsConfig config.Preferences
coreComponentsHolder CoreComponentsHolder
activateBLSPubKeyMessageVerification bool
keyLoader KeyLoaderHandler
Expand All @@ -77,6 +85,7 @@ type cryptoComponents struct {
blockSignKeyGen crypto.KeyGenerator
txSignKeyGen crypto.KeyGenerator
messageSignVerifier vm.MessageSignVerifier
keysHolder heartbeat.KeysHolder
cryptoParams
}

Expand All @@ -97,6 +106,7 @@ func NewCryptoComponentsFactory(args CryptoComponentsFactoryArgs) (*cryptoCompon
validatorKeyPemFileName: args.ValidatorKeyPemFileName,
skIndex: args.SkIndex,
config: args.Config,
prefsConfig: args.PrefsConfig,
coreComponentsHolder: args.CoreComponentsHolder,
activateBLSPubKeyMessageVerification: args.ActivateBLSPubKeyMessageVerification,
keyLoader: args.KeyLoader,
Expand Down Expand Up @@ -167,6 +177,21 @@ func (ccf *cryptoComponentsFactory) Create() (*cryptoComponents, error) {
return nil, err
}

// TODO: refactor the logic for isMainMachine
redundancyLevel := int(ccf.prefsConfig.Preferences.RedundancyLevel)
isMainMachine := redundancyLevel == mainMachineRedundancyLevel
argsKeysHolder := keysManagement.ArgsVirtualPeersHolder{
KeyGenerator: blockSignKeyGen,
P2PIdentityGenerator: p2pCrypto.NewIdentityGenerator(),
IsMainMachine: isMainMachine,
MaxRoundsWithoutReceivedMessages: redundancyLevel,
PrefsConfig: ccf.prefsConfig,
}
keysHolder, err := keysManagement.NewVirtualPeersHolder(argsKeysHolder)
if err != nil {
return nil, err
}

log.Debug("block sign pubkey", "value", cp.publicKeyString)

return &cryptoComponents{
Expand All @@ -177,6 +202,7 @@ func (ccf *cryptoComponentsFactory) Create() (*cryptoComponents, error) {
blockSignKeyGen: blockSignKeyGen,
txSignKeyGen: txSignKeyGen,
messageSignVerifier: messageSignVerifier,
keysHolder: keysHolder,
cryptoParams: *cp,
}, nil
}
Expand Down
17 changes: 17 additions & 0 deletions factory/cryptoComponentsHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ElrondNetwork/elrond-go-core/core/check"
"github.com/ElrondNetwork/elrond-go-crypto"
"github.com/ElrondNetwork/elrond-go/errors"
"github.com/ElrondNetwork/elrond-go/heartbeat"
"github.com/ElrondNetwork/elrond-go/vm"
)

Expand Down Expand Up @@ -104,6 +105,9 @@ func (mcc *managedCryptoComponents) CheckSubcomponents() error {
if check.IfNil(mcc.cryptoComponents.messageSignVerifier) {
return errors.ErrNilMessageSignVerifier
}
if check.IfNil(mcc.cryptoComponents.keysHolder) {
return errors.ErrNilKeysHolder
}

return nil
}
Expand Down Expand Up @@ -265,6 +269,18 @@ func (mcc *managedCryptoComponents) MessageSignVerifier() vm.MessageSignVerifier
return mcc.cryptoComponents.messageSignVerifier
}

// KeysHolder returns the virtual keys holder
func (mcc *managedCryptoComponents) KeysHolder() heartbeat.KeysHolder {
mcc.mutCryptoComponents.RLock()
defer mcc.mutCryptoComponents.RUnlock()

if mcc.cryptoComponents == nil {
return nil
}

return mcc.cryptoComponents.keysHolder
}

// Clone creates a shallow clone of a managedCryptoComponents
func (mcc *managedCryptoComponents) Clone() interface{} {
cryptoComp := (*cryptoComponents)(nil)
Expand All @@ -277,6 +293,7 @@ func (mcc *managedCryptoComponents) Clone() interface{} {
blockSignKeyGen: mcc.BlockSignKeyGen(),
txSignKeyGen: mcc.TxSignKeyGen(),
messageSignVerifier: mcc.MessageSignVerifier(),
keysHolder: mcc.KeysHolder(),
cryptoParams: mcc.cryptoParams,
}
}
Expand Down
2 changes: 2 additions & 0 deletions factory/cryptoComponentsHandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestManagedCryptoComponents_CreateShouldWork(t *testing.T) {
require.Nil(t, managedCryptoComponents.BlockSignKeyGen())
require.Nil(t, managedCryptoComponents.TxSignKeyGen())
require.Nil(t, managedCryptoComponents.MessageSignVerifier())
require.Nil(t, managedCryptoComponents.KeysHolder())

err = managedCryptoComponents.Create()
require.NoError(t, err)
Expand All @@ -52,6 +53,7 @@ func TestManagedCryptoComponents_CreateShouldWork(t *testing.T) {
require.NotNil(t, managedCryptoComponents.BlockSignKeyGen())
require.NotNil(t, managedCryptoComponents.TxSignKeyGen())
require.NotNil(t, managedCryptoComponents.MessageSignVerifier())
require.NotNil(t, managedCryptoComponents.KeysHolder())
}

func TestManagedCryptoComponents_CheckSubcomponents(t *testing.T) {
Expand Down
9 changes: 9 additions & 0 deletions factory/cryptoComponents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,15 @@ func getCryptoArgs(coreComponents factory.CoreComponentsHolder) factory.CryptoCo
},
Hasher: config.TypeConfig{Type: "blake2b"},
},
PrefsConfig: config.Preferences{
Preferences: config.PreferencesConfig{
DestinationShardAsObserver: "",
NodeDisplayName: "node name",
Identity: "identity",
RedundancyLevel: 1,
},
NamedIdentity: nil,
},
SkIndex: 0,
ValidatorKeyPemFileName: "validatorKey.pem",
CoreComponentsHolder: coreComponents,
Expand Down
3 changes: 3 additions & 0 deletions factory/heartbeatV2Components.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ func (hcf *heartbeatV2ComponentsFactory) Create() (*heartbeatV2Components, error
HardforkTrigger: hcf.processComponents.HardforkTrigger(),
HardforkTimeBetweenSends: time.Second * time.Duration(cfg.HardforkTimeBetweenSendsInSec),
HardforkTriggerPubKey: hcf.coreComponents.HardforkTriggerPubKey(),
KeysHolder: hcf.cryptoComponents.KeysHolder(),
PeerAuthenticationTimeBetweenChecks: time.Second * time.Duration(cfg.PeerAuthenticationTimeBetweenChecksInSec),
ShardCoordinator: hcf.processComponents.ShardCoordinator(),
}
heartbeatV2Sender, err := sender.NewSender(argsSender)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions factory/heartbeatV2Components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func createMockHeartbeatV2ComponentsFactoryArgs() factory.ArgHeartbeatV2Componen
MaxDurationPeerUnresponsiveInSec: 10,
HideInactiveValidatorIntervalInSec: 60,
HardforkTimeBetweenSendsInSec: 5,
PeerAuthenticationTimeBetweenChecksInSec: 1,
PeerAuthenticationPool: config.PeerAuthenticationPoolConfig{
DefaultSpanInSec: 30,
CacheExpiryInSec: 30,
Expand Down
1 change: 1 addition & 0 deletions factory/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ type CryptoComponentsHolder interface {
BlockSignKeyGen() crypto.KeyGenerator
TxSignKeyGen() crypto.KeyGenerator
MessageSignVerifier() vm.MessageSignVerifier
KeysHolder() heartbeat.KeysHolder
Clone() interface{}
IsInterfaceNil() bool
}
Expand Down
8 changes: 8 additions & 0 deletions factory/mock/cryptoComponentsMock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"sync"

"github.com/ElrondNetwork/elrond-go-crypto"
"github.com/ElrondNetwork/elrond-go/heartbeat"
"github.com/ElrondNetwork/elrond-go/vm"
)

Expand All @@ -21,6 +22,7 @@ type CryptoComponentsMock struct {
BlKeyGen crypto.KeyGenerator
TxKeyGen crypto.KeyGenerator
MsgSigVerifier vm.MessageSignVerifier
KeysHolderField heartbeat.KeysHolder
mutMultiSig sync.RWMutex
}

Expand Down Expand Up @@ -99,6 +101,11 @@ func (ccm *CryptoComponentsMock) MessageSignVerifier() vm.MessageSignVerifier {
return ccm.MsgSigVerifier
}

// KeysHolder -
func (ccm *CryptoComponentsMock) KeysHolder() heartbeat.KeysHolder {
return ccm.KeysHolderField
}

// Clone -
func (ccm *CryptoComponentsMock) Clone() interface{} {
return &CryptoComponentsMock{
Expand All @@ -114,6 +121,7 @@ func (ccm *CryptoComponentsMock) Clone() interface{} {
BlKeyGen: ccm.BlKeyGen,
TxKeyGen: ccm.TxKeyGen,
MsgSigVerifier: ccm.MsgSigVerifier,
KeysHolderField: ccm.KeysHolderField,
mutMultiSig: sync.RWMutex{},
}
}
Expand Down
3 changes: 3 additions & 0 deletions heartbeat/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,6 @@ var ErrShouldSkipValidator = errors.New("validator should be skipped")

// ErrNilKeysHolder signals that a nil keys holder has been provided
var ErrNilKeysHolder = errors.New("nil keys holder")

// ErrInvalidConfiguration signals that an invalid configuration has been provided
var ErrInvalidConfiguration = errors.New("invalid configuration")
5 changes: 5 additions & 0 deletions heartbeat/sender/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ type hardforkHandler interface {
Close()
}

type peerAuthenticationSenderHandler interface {
senderHandler
hardforkHandler
}

type timerHandler interface {
CreateNewTimer(duration time.Duration)
ExecutionReadyChannel() <-chan time.Time
Expand Down
80 changes: 80 additions & 0 deletions heartbeat/sender/peerAuthenticationSenderFactory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package sender

import (
"fmt"
"time"

"github.com/ElrondNetwork/covalent-indexer-go/process"
crypto "github.com/ElrondNetwork/elrond-go-crypto"
"github.com/ElrondNetwork/elrond-go/heartbeat"
)

type argPeerAuthenticationSenderFactory struct {
argBaseSender
nodesCoordinator heartbeat.NodesCoordinator
peerSignatureHandler crypto.PeerSignatureHandler
hardforkTrigger heartbeat.HardforkTrigger
hardforkTimeBetweenSends time.Duration
hardforkTriggerPubKey []byte
keysHolder heartbeat.KeysHolder
timeBetweenChecks time.Duration
shardCoordinator process.ShardCoordinator
privKey crypto.PrivateKey
redundancyHandler heartbeat.NodeRedundancyHandler
}

func createPeerAuthenticationSender(args argPeerAuthenticationSenderFactory) (peerAuthenticationSenderHandler, error) {
pk := args.privKey.GeneratePublic()
pkBytes, err := pk.ToByteArray()
if err != nil {
return nil, err
}

keysMap := args.keysHolder.GetManagedKeysByCurrentNode()
isMultikeyMode := len(keysMap) > 0
_, _, err = args.nodesCoordinator.GetValidatorWithPublicKey(pkBytes)
if err == nil {
if isMultikeyMode {
return nil, fmt.Errorf("%w while creating peer authentication, could not determine node's type", heartbeat.ErrInvalidConfiguration)
}

return createRegularSender(args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a check here for len(keysMap) and allow to create the regular peer only if that len is 0. Otherwise we should output error

}

if !isMultikeyMode {
return createRegularSender(args)
}

return createMultikeySender(args)
}

func createRegularSender(args argPeerAuthenticationSenderFactory) (*peerAuthenticationSender, error) {
argsSender := argPeerAuthenticationSender{
argBaseSender: args.argBaseSender,
nodesCoordinator: args.nodesCoordinator,
peerSignatureHandler: args.peerSignatureHandler,
privKey: args.privKey,
redundancyHandler: args.redundancyHandler,
hardforkTrigger: args.hardforkTrigger,
hardforkTimeBetweenSends: args.hardforkTimeBetweenSends,
hardforkTriggerPubKey: args.hardforkTriggerPubKey,
}

return newPeerAuthenticationSender(argsSender)
}

func createMultikeySender(args argPeerAuthenticationSenderFactory) (*multikeyPeerAuthenticationSender, error) {
argsSender := argMultikeyPeerAuthenticationSender{
argBaseSender: args.argBaseSender,
nodesCoordinator: args.nodesCoordinator,
peerSignatureHandler: args.peerSignatureHandler,
hardforkTrigger: args.hardforkTrigger,
hardforkTimeBetweenSends: args.hardforkTimeBetweenSends,
hardforkTriggerPubKey: args.hardforkTriggerPubKey,
keysHolder: args.keysHolder,
timeBetweenChecks: args.timeBetweenChecks,
shardCoordinator: args.shardCoordinator,
}

return newMultikeyPeerAuthenticationSender(argsSender)
}