From fdd18c8b9189ea57b9d6cf2fd111f7b4bf19aa58 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Tue, 23 Jul 2024 17:24:54 +0200 Subject: [PATCH 1/8] align share in qbft --- cli/operator/node.go | 6 ++-- ibft/genesisstorage/store_test.go | 4 +-- network/p2p/p2p_pubsub.go | 11 -------- operator/validator/controller.go | 24 ++++++++++++++-- protocol/genesis/qbft/config.go | 7 ++--- .../genesis/qbft/controller/controller.go | 13 ++++----- protocol/genesis/qbft/controller/decided.go | 16 +++++------ .../qbft/controller/highest_instance.go | 2 +- protocol/genesis/qbft/instance/commit.go | 13 ++++----- protocol/genesis/qbft/instance/compact.go | 7 ++--- .../genesis/qbft/instance/compact_test.go | 8 +++--- protocol/genesis/qbft/instance/instance.go | 16 +++++------ protocol/genesis/qbft/instance/messages.go | 7 +++-- protocol/genesis/qbft/instance/prepare.go | 17 ++++++----- protocol/genesis/qbft/instance/proposal.go | 28 +++++++++---------- .../genesis/qbft/instance/round_change.go | 28 +++++++++---------- protocol/genesis/qbft/storage/ibft_store.go | 3 +- protocol/genesis/ssv/runner/compact.go | 2 +- .../ssv/validator/non_committee_validator.go | 21 +++++++++++++- protocol/genesis/types/crypto.go | 5 ++-- protocol/genesis/types/state.go | 13 +-------- 21 files changed, 128 insertions(+), 123 deletions(-) diff --git a/cli/operator/node.go b/cli/operator/node.go index e1fab74802..cb16e1c69c 100644 --- a/cli/operator/node.go +++ b/cli/operator/node.go @@ -4,13 +4,14 @@ import ( "context" "encoding/base64" "fmt" - genesisssvtypes "github.com/ssvlabs/ssv/protocol/genesis/types" "log" "math/big" "net/http" "os" "time" + genesisssvtypes "github.com/ssvlabs/ssv/protocol/genesis/types" + ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ilyakaznacheev/cleanenv" "github.com/pkg/errors" @@ -266,8 +267,7 @@ var StartNodeCmd = &cobra.Command{ cfg.SSVOptions.ValidatorOptions.RecipientsStorage = nodeStorage cfg.SSVOptions.ValidatorOptions.GasLimit = cfg.ConsensusClient.GasLimit - genesisKeyManager := &ekm.GenesisKeyManagerAdapter{KeyManager: keyManager} - cfg.SSVOptions.ValidatorOptions.GenesisControllerOptions.KeyManager = genesisKeyManager + cfg.SSVOptions.ValidatorOptions.GenesisControllerOptions.KeyManager = &ekm.GenesisKeyManagerAdapter{KeyManager: keyManager} if cfg.WsAPIPort != 0 { ws := exporterapi.NewWsServer(cmd.Context(), nil, http.NewServeMux(), cfg.WithPing) diff --git a/ibft/genesisstorage/store_test.go b/ibft/genesisstorage/store_test.go index a7d08ccc43..4eee7d3ac5 100644 --- a/ibft/genesisstorage/store_test.go +++ b/ibft/genesisstorage/store_test.go @@ -97,7 +97,7 @@ func TestSaveAndFetchLastState(t *testing.T) { instance := &genesisqbftstorage.StoredInstance{ State: &types.State{ - CommitteeMember: nil, + Share: nil, ID: identifier[:], Round: 1, Height: 1, @@ -135,7 +135,7 @@ func TestSaveAndFetchState(t *testing.T) { instance := &genesisqbftstorage.StoredInstance{ State: &types.State{ - CommitteeMember: nil, + Share: nil, ID: identifier[:], Round: 1, Height: 1, diff --git a/network/p2p/p2p_pubsub.go b/network/p2p/p2p_pubsub.go index 943040df2a..4ecb3015ca 100644 --- a/network/p2p/p2p_pubsub.go +++ b/network/p2p/p2p_pubsub.go @@ -68,17 +68,6 @@ func (n *p2pNetwork) Broadcast(msgID spectypes.MessageID, msg *spectypes.SignedS return fmt.Errorf("operator ID is not ready") } - // TODO: (genesis) old encoding - // encodedMsg, err := commons.EncodeNetworkMsg(msg) - // if err != nil { - // return errors.Wrap(err, "could not decode msg") - // } - // signature, err := n.operatorSigner.Sign(encodedMsg) - // if err != nil { - // return err - // } - // encodedMsg = commons.EncodeSignedSSVMessage(encodedMsg, n.operatorDataStore.GetOperatorID(), signature) - encodedMsg, err := msg.Encode() if err != nil { return fmt.Errorf("could not encode signed ssv message: %w", err) diff --git a/operator/validator/controller.go b/operator/validator/controller.go index 44a165b5cc..92be62d2a2 100644 --- a/operator/validator/controller.go +++ b/operator/validator/controller.go @@ -1461,14 +1461,32 @@ func SetupGenesisRunners(ctx context.Context, logger *zap.Logger, options valida genesisspectypes.BNRoleVoluntaryExit, } + share := &genesisspectypes.Share{} + + share.OperatorID = options.Operator.OperatorID + share.ValidatorPubKey = options.SSVShare.Share.ValidatorPubKey[:] + share.SharePubKey = options.SSVShare.Share.SharePubKey + share.Committee = make([]*genesisspectypes.Operator, len(options.SSVShare.Share.Committee)) + for _, c := range options.SSVShare.Share.Committee { + share.Committee = append(share.Committee, &genesisspectypes.Operator{ + OperatorID: c.Signer, + PubKey: c.SharePubKey, + }) + } + + share.Quorum = options.Operator.GetQuorum() + share.DomainType = genesisspectypes.DomainType(options.SSVShare.Share.DomainType) + share.FeeRecipientAddress = options.SSVShare.Share.FeeRecipientAddress + share.Graffiti = options.SSVShare.Share.Graffiti + buildController := func(role genesisspectypes.BeaconRole, valueCheckF genesisspecqbft.ProposedValueCheckF) *genesisqbftcontroller.Controller { config := &genesisqbft.Config{ Signer: options.GenesisOptions.Signer, SigningPK: options.SSVShare.ValidatorPubKey[:], Domain: genesisssvtypes.GetDefaultDomain(), ValueCheckF: nil, // sets per role type - ProposerF: func(state *genesisssvtypes.State, round genesisspecqbft.Round) genesisspectypes.OperatorID { - leader := genesisssvtypes.RoundRobinProposer(state, round) + ProposerF: func(state *genesisspecqbft.State, round genesisspecqbft.Round) genesisspectypes.OperatorID { + leader := genesisspecqbft.RoundRobinProposer(state, round) //logger.Debug("leader", zap.Int("operator_id", int(leader))) return leader }, @@ -1481,7 +1499,7 @@ func SetupGenesisRunners(ctx context.Context, logger *zap.Logger, options valida config.ValueCheckF = valueCheckF identifier := genesisspectypes.NewMsgID(genesisssvtypes.GetDefaultDomain(), options.SSVShare.Share.ValidatorPubKey[:], role) - qbftCtrl := genesisqbftcontroller.NewController(identifier[:], options.Operator, config, options.FullNode) + qbftCtrl := genesisqbftcontroller.NewController(identifier[:], share, config, options.FullNode) qbftCtrl.NewDecidedHandler = options.GenesisOptions.NewDecidedHandler return qbftCtrl } diff --git a/protocol/genesis/qbft/config.go b/protocol/genesis/qbft/config.go index ca22f0dfe3..b436caffd5 100644 --- a/protocol/genesis/qbft/config.go +++ b/protocol/genesis/qbft/config.go @@ -6,7 +6,6 @@ import ( "github.com/ssvlabs/ssv/protocol/genesis/qbft/roundtimer" qbftstorage "github.com/ssvlabs/ssv/protocol/genesis/qbft/storage" - "github.com/ssvlabs/ssv/protocol/genesis/types" ) type signing interface { @@ -21,7 +20,7 @@ type IConfig interface { // GetValueCheckF returns value check function GetValueCheckF() genesisspecqbft.ProposedValueCheckF // GetProposerF returns func used to calculate proposer - GetProposerF() func(state *types.State, round genesisspecqbft.Round) genesisspectypes.OperatorID + GetProposerF() genesisspecqbft.ProposerF // GetNetwork returns a p2p Network instance GetNetwork() genesisspecqbft.Network // GetStorage returns a storage instance @@ -39,7 +38,7 @@ type Config struct { SigningPK []byte Domain genesisspectypes.DomainType ValueCheckF genesisspecqbft.ProposedValueCheckF - ProposerF func(state *types.State, round genesisspecqbft.Round) genesisspectypes.OperatorID + ProposerF genesisspecqbft.ProposerF Storage qbftstorage.QBFTStore Network genesisspecqbft.Network Timer roundtimer.Timer @@ -68,7 +67,7 @@ func (c *Config) GetValueCheckF() genesisspecqbft.ProposedValueCheckF { } // GetProposerF returns func used to calculate proposer -func (c *Config) GetProposerF() func(state *types.State, round genesisspecqbft.Round) genesisspectypes.OperatorID { +func (c *Config) GetProposerF() genesisspecqbft.ProposerF { return c.ProposerF } diff --git a/protocol/genesis/qbft/controller/controller.go b/protocol/genesis/qbft/controller/controller.go index 1fa250bcae..7af60c67e7 100644 --- a/protocol/genesis/qbft/controller/controller.go +++ b/protocol/genesis/qbft/controller/controller.go @@ -10,7 +10,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -28,7 +27,7 @@ type Controller struct { Height genesisspecqbft.Height // incremental Height for InstanceContainer // StoredInstances stores the last HistoricalInstanceCapacity in an array for message processing purposes. StoredInstances InstanceContainer - CommitteeMember *spectypes.CommitteeMember + Share *genesisspectypes.Share NewDecidedHandler NewDecidedHandler `json:"-"` config qbft.IConfig fullNode bool @@ -36,14 +35,14 @@ type Controller struct { func NewController( identifier []byte, - committeeMember *spectypes.CommitteeMember, + share *genesisspectypes.Share, config qbft.IConfig, fullNode bool, ) *Controller { return &Controller{ Identifier: identifier, Height: genesisspecqbft.FirstHeight, - CommitteeMember: committeeMember, + Share: share, StoredInstances: make(InstanceContainer, 0, InstanceContainerDefaultCapacity), config: config, fullNode: fullNode, @@ -94,7 +93,7 @@ func (c *Controller) ProcessMsg(logger *zap.Logger, msg *genesisspecqbft.SignedM All valid future msgs are saved in a container and can trigger highest decided futuremsg All other msgs (not future or decided) are processed normally by an existing instance (if found) */ - if IsDecidedMsg(c.CommitteeMember, msg) { + if IsDecidedMsg(c.Share, msg) { return c.UponDecided(logger, msg) } else if c.isFutureMessage(msg) { return nil, fmt.Errorf("future msg from height, could not process") @@ -169,7 +168,7 @@ func (c *Controller) InstanceForHeight(logger *zap.Logger, height genesisspecqbf if storedInst == nil { return nil } - inst := instance.NewInstance(c.config, c.CommitteeMember, c.Identifier, storedInst.State.Height) + inst := instance.NewInstance(c.config, c.Share, c.Identifier, storedInst.State.Height) inst.State = storedInst.State return inst } @@ -190,7 +189,7 @@ func (c *Controller) isFutureMessage(msg *genesisspecqbft.SignedMessage) bool { // addAndStoreNewInstance returns creates a new QBFT instance, stores it in an array and returns it func (c *Controller) addAndStoreNewInstance() *instance.Instance { - i := instance.NewInstance(c.GetConfig(), c.CommitteeMember, c.Identifier, c.Height) + i := instance.NewInstance(c.GetConfig(), c.Share, c.Identifier, c.Height) c.StoredInstances.addNewInstance(i) return i } diff --git a/protocol/genesis/qbft/controller/decided.go b/protocol/genesis/qbft/controller/decided.go index c9736a131e..dfc54c49a9 100644 --- a/protocol/genesis/qbft/controller/decided.go +++ b/protocol/genesis/qbft/controller/decided.go @@ -5,7 +5,7 @@ import ( "github.com/pkg/errors" genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" + genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/protocol/genesis/qbft" @@ -17,7 +17,7 @@ func (c *Controller) UponDecided(logger *zap.Logger, msg *genesisspecqbft.Signed if err := ValidateDecided( c.config, msg, - c.CommitteeMember, + c.Share, ); err != nil { return nil, errors.Wrap(err, "invalid decided msg") } @@ -29,7 +29,7 @@ func (c *Controller) UponDecided(logger *zap.Logger, msg *genesisspecqbft.Signed save := true if inst == nil { - i := instance.NewInstance(c.GetConfig(), c.CommitteeMember, c.Identifier, msg.Message.Height) + i := instance.NewInstance(c.GetConfig(), c.Share, c.Identifier, msg.Message.Height) i.State.Round = msg.Message.Round i.State.Decided = true i.State.DecidedValue = msg.FullData @@ -82,9 +82,9 @@ func (c *Controller) UponDecided(logger *zap.Logger, msg *genesisspecqbft.Signed func ValidateDecided( config qbft.IConfig, signedDecided *genesisspecqbft.SignedMessage, - committeeMemeber *spectypes.CommitteeMember, + share *genesisspectypes.Share, ) error { - if !IsDecidedMsg(committeeMemeber, signedDecided) { + if !IsDecidedMsg(share, signedDecided) { return errors.New("not a decided msg") } @@ -92,7 +92,7 @@ func ValidateDecided( return errors.Wrap(err, "invalid decided msg") } - if err := instance.BaseCommitValidation(config, signedDecided, signedDecided.Message.Height, committeeMemeber.Committee); err != nil { + if err := instance.BaseCommitValidation(config, signedDecided, signedDecided.Message.Height, share.Committee); err != nil { return errors.Wrap(err, "invalid decided msg") } @@ -112,6 +112,6 @@ func ValidateDecided( } // IsDecidedMsg returns true if signed commit has all quorum sigs -func IsDecidedMsg(committeeMember *spectypes.CommitteeMember, signedDecided *genesisspecqbft.SignedMessage) bool { - return committeeMember.HasQuorum(len(signedDecided.Signers)) && signedDecided.Message.MsgType == genesisspecqbft.CommitMsgType +func IsDecidedMsg(share *genesisspectypes.Share, signedDecided *genesisspecqbft.SignedMessage) bool { + return share.HasQuorum(len(signedDecided.Signers)) && signedDecided.Message.MsgType == genesisspecqbft.CommitMsgType } diff --git a/protocol/genesis/qbft/controller/highest_instance.go b/protocol/genesis/qbft/controller/highest_instance.go index 0ded63619c..a99a4774ed 100644 --- a/protocol/genesis/qbft/controller/highest_instance.go +++ b/protocol/genesis/qbft/controller/highest_instance.go @@ -36,7 +36,7 @@ func (c *Controller) getHighestInstance(identifier []byte) (*instance.Instance, i := instance.NewInstance( c.config, - highestInstance.State.CommitteeMember, + highestInstance.State.Share, identifier, highestInstance.State.Height, ) diff --git a/protocol/genesis/qbft/instance/commit.go b/protocol/genesis/qbft/instance/commit.go index 1ac43beaec..4335ae4cde 100644 --- a/protocol/genesis/qbft/instance/commit.go +++ b/protocol/genesis/qbft/instance/commit.go @@ -8,7 +8,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -60,9 +59,9 @@ func (i *Instance) UponCommit(logger *zap.Logger, signedCommit *genesisspecqbft. } // returns true if there is a quorum for the current round for this provided value -func commitQuorumForRoundRoot(state *types.State, commitMsgContainer *genesisspecqbft.MsgContainer, root [32]byte, round genesisspecqbft.Round) (bool, []*genesisspecqbft.SignedMessage, error) { +func commitQuorumForRoundRoot(state *genesisspecqbft.State, commitMsgContainer *genesisspecqbft.MsgContainer, root [32]byte, round genesisspecqbft.Round) (bool, []*genesisspecqbft.SignedMessage, error) { signers, msgs := commitMsgContainer.LongestUniqueSignersForRoundAndRoot(round, root) - return state.CommitteeMember.HasQuorum(len(signers)), msgs, nil + return state.Share.HasQuorum(len(signers)), msgs, nil } func aggregateCommitMsgs(msgs []*genesisspecqbft.SignedMessage, fullData []byte) (*genesisspecqbft.SignedMessage, error) { @@ -103,7 +102,7 @@ Commit( ) ); */ -func CreateCommit(state *types.State, config qbft.IConfig, root [32]byte) (*genesisspecqbft.SignedMessage, error) { +func CreateCommit(state *genesisspecqbft.State, config qbft.IConfig, root [32]byte) (*genesisspecqbft.SignedMessage, error) { msg := &genesisspecqbft.Message{ MsgType: genesisspecqbft.CommitMsgType, Height: state.Height, @@ -112,7 +111,7 @@ func CreateCommit(state *types.State, config qbft.IConfig, root [32]byte) (*gene Root: root, } - sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.CommitteeMember.SSVOperatorPubKey) + sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.Share.SharePubKey) if err != nil { return nil, errors.Wrap(err, "failed signing commit msg") } @@ -129,7 +128,7 @@ func BaseCommitValidation( config qbft.IConfig, signedCommit *genesisspecqbft.SignedMessage, height genesisspecqbft.Height, - operators []*spectypes.Operator, + operators []*genesisspectypes.Operator, ) error { if signedCommit.Message.MsgType != genesisspecqbft.CommitMsgType { return errors.New("commit msg type is wrong") @@ -157,7 +156,7 @@ func validateCommit( height genesisspecqbft.Height, round genesisspecqbft.Round, proposedMsg *genesisspecqbft.SignedMessage, - operators []*spectypes.Operator, + operators []*genesisspectypes.Operator, ) error { if err := BaseCommitValidation(config, signedCommit, height, operators); err != nil { return err diff --git a/protocol/genesis/qbft/instance/compact.go b/protocol/genesis/qbft/instance/compact.go index 8af6626b81..60a1fe5c7d 100644 --- a/protocol/genesis/qbft/instance/compact.go +++ b/protocol/genesis/qbft/instance/compact.go @@ -2,7 +2,6 @@ package instance import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" - "github.com/ssvlabs/ssv/protocol/genesis/types" ) // Compact trims the given qbft.State down to the minimum required @@ -12,7 +11,7 @@ import ( // Compact discards all non-commit messages, only if the given state is decided. // // This helps reduce the state's memory footprint. -func Compact(state *types.State, decidedMessage *genesisspecqbft.SignedMessage) { +func Compact(state *genesisspecqbft.State, decidedMessage *genesisspecqbft.SignedMessage) { compact(state, decidedMessage, compactContainerEdit) } @@ -23,13 +22,13 @@ func Compact(state *types.State, decidedMessage *genesisspecqbft.SignedMessage) // TODO: this is a temporary solution to not break spec-tests. Revert this once spec is aligned. // // See Compact for more details. -func CompactCopy(state *types.State, decidedMessage *genesisspecqbft.SignedMessage) *types.State { +func CompactCopy(state *genesisspecqbft.State, decidedMessage *genesisspecqbft.SignedMessage) *genesisspecqbft.State { stateCopy := *state compact(&stateCopy, decidedMessage, compactContainerCopy) return &stateCopy } -func compact(state *types.State, decidedMessage *genesisspecqbft.SignedMessage, compactContainer compactContainerFunc) { +func compact(state *genesisspecqbft.State, decidedMessage *genesisspecqbft.SignedMessage, compactContainer compactContainerFunc) { state.ProposeContainer = compactContainer(state.ProposeContainer, state.Round, state.Decided) state.PrepareContainer = compactContainer(state.PrepareContainer, state.LastPreparedRound, state.Decided) state.RoundChangeContainer = compactContainer(state.RoundChangeContainer, state.Round, state.Decided) diff --git a/protocol/genesis/qbft/instance/compact_test.go b/protocol/genesis/qbft/instance/compact_test.go index caf5589b04..49fb9477e2 100644 --- a/protocol/genesis/qbft/instance/compact_test.go +++ b/protocol/genesis/qbft/instance/compact_test.go @@ -87,7 +87,7 @@ var compactTests = []struct { Round: 3, LastPreparedRound: 3, Decided: true, - CommitteeMember: &spectypes.CommitteeMember{ + Share: &spectypes.CommitteeMember{ Committee: make([]*spectypes.Operator, 4), }, ProposeContainer: mockContainer(1, 2, 3, 4), @@ -102,7 +102,7 @@ var compactTests = []struct { Round: 3, LastPreparedRound: 3, Decided: true, - CommitteeMember: &spectypes.CommitteeMember{ + Share: &spectypes.CommitteeMember{ Committee: make([]*spectypes.Operator, 4), }, ProposeContainer: mockContainer(), @@ -117,7 +117,7 @@ var compactTests = []struct { Round: 2, LastPreparedRound: 2, Decided: true, - CommitteeMember: &spectypes.CommitteeMember{ + Share: &spectypes.CommitteeMember{ Committee: make([]*spectypes.Operator, 4), }, ProposeContainer: mockContainer(1, 2, 3, 4), @@ -132,7 +132,7 @@ var compactTests = []struct { Round: 2, LastPreparedRound: 2, Decided: true, - CommitteeMember: &spectypes.CommitteeMember{ + Share: &spectypes.CommitteeMember{ Committee: make([]*spectypes.Operator, 4), }, ProposeContainer: mockContainer(), diff --git a/protocol/genesis/qbft/instance/instance.go b/protocol/genesis/qbft/instance/instance.go index b526b71fd3..a4ae29f6a3 100644 --- a/protocol/genesis/qbft/instance/instance.go +++ b/protocol/genesis/qbft/instance/instance.go @@ -10,17 +10,15 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/protocol/genesis/qbft" - "github.com/ssvlabs/ssv/protocol/genesis/types" ) // Instance is a single QBFT instance that starts with a Start call (including a value). // Every new msg the ProcessMsg function needs to be called type Instance struct { - State *types.State + State *genesisspecqbft.State config qbft.IConfig processMsgF *genesisspectypes.ThreadSafeF @@ -34,14 +32,14 @@ type Instance struct { func NewInstance( config qbft.IConfig, - committeeMember *spectypes.CommitteeMember, + share *genesisspectypes.Share, identifier []byte, height genesisspecqbft.Height, ) *Instance { msgId := genesisspectypes.MessageIDFromBytes(identifier) return &Instance{ - State: &types.State{ - CommitteeMember: committeeMember, + State: &genesisspecqbft.State{ + Share: share, ID: identifier, Round: genesisspecqbft.FirstRound, Height: height, @@ -176,7 +174,7 @@ func (i *Instance) BaseMsgValidation(msg *genesisspecqbft.SignedMessage) error { i.config, msg, i.config.GetValueCheckF(), - i.State.CommitteeMember.Committee, + i.State.Share.Committee, ) case genesisspecqbft.PrepareMsgType: proposedMsg := i.State.ProposalAcceptedForCurrentRound @@ -189,7 +187,7 @@ func (i *Instance) BaseMsgValidation(msg *genesisspecqbft.SignedMessage) error { i.State.Height, i.State.Round, proposedMsg.Message.Root, - i.State.CommitteeMember.Committee, + i.State.Share.Committee, ) case genesisspecqbft.CommitMsgType: proposedMsg := i.State.ProposalAcceptedForCurrentRound @@ -202,7 +200,7 @@ func (i *Instance) BaseMsgValidation(msg *genesisspecqbft.SignedMessage) error { i.State.Height, i.State.Round, i.State.ProposalAcceptedForCurrentRound, - i.State.CommitteeMember.Committee, + i.State.Share.Committee, ) case genesisspecqbft.RoundChangeMsgType: return validRoundChangeForData(i.State, i.config, msg, i.State.Height, msg.Message.Round, msg.FullData) diff --git a/protocol/genesis/qbft/instance/messages.go b/protocol/genesis/qbft/instance/messages.go index dff9fd7a89..f99546af61 100644 --- a/protocol/genesis/qbft/instance/messages.go +++ b/protocol/genesis/qbft/instance/messages.go @@ -2,6 +2,7 @@ package instance import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" + genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" spectypes "github.com/ssvlabs/ssv-spec/types" ssvtypes "github.com/ssvlabs/ssv/protocol/v2/types" @@ -23,7 +24,7 @@ func CheckSignersInCommittee(signedMsg *genesisspecqbft.SignedMessage, committee return true } -func HasQuorum(share *spectypes.CommitteeMember, msgs []*genesisspecqbft.SignedMessage) bool { +func HasQuorum(share *genesisspectypes.Share, msgs []*genesisspecqbft.SignedMessage) bool { uniqueSigners := make(map[spectypes.OperatorID]bool) for _, msg := range msgs { for _, signer := range msg.GetSigners() { @@ -34,8 +35,8 @@ func HasQuorum(share *spectypes.CommitteeMember, msgs []*genesisspecqbft.SignedM } // HasPartialQuorum returns true if a unique set of signers has partial quorum -func HasPartialQuorum(share *spectypes.CommitteeMember, msgs []*genesisspecqbft.SignedMessage) bool { - uniqueSigners := make(map[spectypes.OperatorID]bool) +func HasPartialQuorum(share *genesisspectypes.Share, msgs []*genesisspecqbft.SignedMessage) bool { + uniqueSigners := make(map[genesisspectypes.OperatorID]bool) for _, msg := range msgs { for _, signer := range msg.GetSigners() { uniqueSigners[signer] = true diff --git a/protocol/genesis/qbft/instance/prepare.go b/protocol/genesis/qbft/instance/prepare.go index 7e49b46ae5..1f3f8d8803 100644 --- a/protocol/genesis/qbft/instance/prepare.go +++ b/protocol/genesis/qbft/instance/prepare.go @@ -7,7 +7,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -18,7 +17,7 @@ import ( // uponPrepare process prepare message // Assumes prepare message is valid! func (i *Instance) uponPrepare(logger *zap.Logger, signedPrepare *genesisspecqbft.SignedMessage, prepareMsgContainer *genesisspecqbft.MsgContainer) error { - hasQuorumBefore := HasQuorum(i.State.CommitteeMember, prepareMsgContainer.MessagesForRound(i.State.Round)) + hasQuorumBefore := HasQuorum(i.State.Share, prepareMsgContainer.MessagesForRound(i.State.Round)) addedMsg, err := prepareMsgContainer.AddFirstMsgForSignerAndRound(signedPrepare) if err != nil { @@ -37,7 +36,7 @@ func (i *Instance) uponPrepare(logger *zap.Logger, signedPrepare *genesisspecqbf return nil // already moved to commit stage } - if !HasQuorum(i.State.CommitteeMember, prepareMsgContainer.MessagesForRound(i.State.Round)) { + if !HasQuorum(i.State.Share, prepareMsgContainer.MessagesForRound(i.State.Round)) { return nil // no quorum yet } @@ -72,7 +71,7 @@ func (i *Instance) uponPrepare(logger *zap.Logger, signedPrepare *genesisspecqbf // getRoundChangeJustification returns the round change justification for the current round. // The justification is a quorum of signed prepare messages that agree on state.LastPreparedValue -func getRoundChangeJustification(state *types.State, config qbft.IConfig, prepareMsgContainer *genesisspecqbft.MsgContainer) ([]*genesisspecqbft.SignedMessage, error) { +func getRoundChangeJustification(state *genesisspecqbft.State, config qbft.IConfig, prepareMsgContainer *genesisspecqbft.MsgContainer) ([]*genesisspecqbft.SignedMessage, error) { if state.LastPreparedValue == nil { return nil, nil } @@ -91,13 +90,13 @@ func getRoundChangeJustification(state *types.State, config qbft.IConfig, prepar state.Height, state.LastPreparedRound, r, - state.CommitteeMember.Committee, + state.Share.Committee, ); err == nil { ret = append(ret, msg) } } - if !HasQuorum(state.CommitteeMember, ret) { + if !HasQuorum(state.Share, ret) { return nil, nil } @@ -135,7 +134,7 @@ func validSignedPrepareForHeightRoundAndRoot( height genesisspecqbft.Height, round genesisspecqbft.Round, root [32]byte, - operators []*spectypes.Operator) error { + operators []*genesisspectypes.Operator) error { if signedPrepare.Message.MsgType != genesisspecqbft.PrepareMsgType { return errors.New("prepare msg type is wrong") } @@ -179,7 +178,7 @@ Prepare( ) ); */ -func CreatePrepare(state *types.State, config qbft.IConfig, newRound genesisspecqbft.Round, root [32]byte) (*genesisspecqbft.SignedMessage, error) { +func CreatePrepare(state *genesisspecqbft.State, config qbft.IConfig, newRound genesisspecqbft.Round, root [32]byte) (*genesisspecqbft.SignedMessage, error) { msg := &genesisspecqbft.Message{ MsgType: genesisspecqbft.PrepareMsgType, Height: state.Height, @@ -188,7 +187,7 @@ func CreatePrepare(state *types.State, config qbft.IConfig, newRound genesisspec Root: root, } - sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.CommitteeMember.SSVOperatorPubKey) + sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.Share.SharePubKey) if err != nil { return nil, errors.Wrap(err, "failed signing prepare msg") } diff --git a/protocol/genesis/qbft/instance/proposal.go b/protocol/genesis/qbft/instance/proposal.go index dbcabb3324..7c8bc7b503 100644 --- a/protocol/genesis/qbft/instance/proposal.go +++ b/protocol/genesis/qbft/instance/proposal.go @@ -7,12 +7,10 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" "github.com/ssvlabs/ssv/protocol/genesis/qbft" - "github.com/ssvlabs/ssv/protocol/genesis/types" genesisssvtypes "github.com/ssvlabs/ssv/protocol/genesis/types" ) @@ -65,11 +63,11 @@ func (i *Instance) uponProposal(logger *zap.Logger, signedProposal *genesisspecq } func isValidProposal( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, signedProposal *genesisspecqbft.SignedMessage, valCheck genesisspecqbft.ProposedValueCheckF, - operators []*spectypes.Operator, + operators []*genesisspectypes.Operator, ) error { if signedProposal.Message.MsgType != genesisspecqbft.ProposalMsgType { return errors.New("msg type is not proposal") @@ -128,7 +126,7 @@ func isValidProposal( func IsProposalJustification( config qbft.IConfig, - committeeMember *spectypes.CommitteeMember, + share *genesisspectypes.Share, roundChangeMsgs []*genesisspecqbft.SignedMessage, prepareMsgs []*genesisspecqbft.SignedMessage, height genesisspecqbft.Height, @@ -136,9 +134,9 @@ func IsProposalJustification( fullData []byte, ) error { return isProposalJustification( - &types.State{ - CommitteeMember: committeeMember, - Height: height, + &genesisspecqbft.State{ + Share: share, + Height: height, }, config, roundChangeMsgs, @@ -152,7 +150,7 @@ func IsProposalJustification( // isProposalJustification returns nil if the proposal and round change messages are valid and justify a proposal message for the provided round, value and leader func isProposalJustification( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, roundChangeMsgs []*genesisspecqbft.SignedMessage, prepareMsgs []*genesisspecqbft.SignedMessage, @@ -178,7 +176,7 @@ func isProposalJustification( } // check there is a quorum - if !HasQuorum(state.CommitteeMember, roundChangeMsgs) { + if !HasQuorum(state.Share, roundChangeMsgs) { return errors.New("change round has no quorum") } @@ -200,7 +198,7 @@ func isProposalJustification( } else { // check prepare quorum - if !HasQuorum(state.CommitteeMember, prepareMsgs) { + if !HasQuorum(state.Share, prepareMsgs) { return errors.New("prepares has no quorum") } @@ -230,7 +228,7 @@ func isProposalJustification( height, rcm.Message.DataRound, rcm.Message.Root, - state.CommitteeMember.Committee, + state.Share.Committee, ); err != nil { return errors.New("signed prepare not valid") } @@ -240,7 +238,7 @@ func isProposalJustification( } } -func proposer(state *types.State, config qbft.IConfig, round genesisspecqbft.Round) genesisspectypes.OperatorID { +func proposer(state *genesisspecqbft.State, config qbft.IConfig, round genesisspecqbft.Round) genesisspectypes.OperatorID { // TODO - https://github.com/ConsenSys/qbft-formal-spec-and-verification/blob/29ae5a44551466453a84d4d17b9e083ecf189d97/dafny/spec/L1/node_auxiliary_functions.dfy#L304-L323 return config.GetProposerF()(state, round) } @@ -258,7 +256,7 @@ func proposer(state *types.State, config qbft.IConfig, round genesisspecqbft.Rou extractSignedRoundChanges(roundChanges), extractSignedPrepares(prepares)); */ -func CreateProposal(state *types.State, config qbft.IConfig, fullData []byte, roundChanges, prepares []*genesisspecqbft.SignedMessage) (*genesisspecqbft.SignedMessage, error) { +func CreateProposal(state *genesisspecqbft.State, config qbft.IConfig, fullData []byte, roundChanges, prepares []*genesisspecqbft.SignedMessage) (*genesisspecqbft.SignedMessage, error) { r, err := genesisspecqbft.HashDataRoot(fullData) if err != nil { return nil, errors.Wrap(err, "could not hash input data") @@ -283,7 +281,7 @@ func CreateProposal(state *types.State, config qbft.IConfig, fullData []byte, ro RoundChangeJustification: roundChangesData, PrepareJustification: preparesData, } - sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.CommitteeMember.SSVOperatorPubKey) + sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.Share.SharePubKey) if err != nil { return nil, errors.Wrap(err, "failed signing proposal msg") } diff --git a/protocol/genesis/qbft/instance/round_change.go b/protocol/genesis/qbft/instance/round_change.go index caa7ffe05f..78f902ff03 100644 --- a/protocol/genesis/qbft/instance/round_change.go +++ b/protocol/genesis/qbft/instance/round_change.go @@ -23,7 +23,7 @@ func (i *Instance) uponRoundChange( roundChangeMsgContainer *genesisspecqbft.MsgContainer, valCheck genesisspecqbft.ProposedValueCheckF, ) error { - hasQuorumBefore := HasQuorum(i.State.CommitteeMember, roundChangeMsgContainer.MessagesForRound(signedRoundChange.Message. + hasQuorumBefore := HasQuorum(i.State.Share, roundChangeMsgContainer.MessagesForRound(signedRoundChange.Message. Round)) // Currently, even if we have a quorum of round change messages, we update the container addedMsg, err := roundChangeMsgContainer.AddFirstMsgForSignerAndRound(signedRoundChange) @@ -118,7 +118,7 @@ func (i *Instance) uponChangeRoundPartialQuorum(logger *zap.Logger, newRound gen return nil } -func hasReceivedPartialQuorum(state *types.State, roundChangeMsgContainer *genesisspecqbft.MsgContainer) (bool, []*genesisspecqbft.SignedMessage) { +func hasReceivedPartialQuorum(state *genesisspecqbft.State, roundChangeMsgContainer *genesisspecqbft.MsgContainer) (bool, []*genesisspecqbft.SignedMessage) { all := roundChangeMsgContainer.AllMessaged() rc := make([]*genesisspecqbft.SignedMessage, 0) @@ -128,7 +128,7 @@ func hasReceivedPartialQuorum(state *types.State, roundChangeMsgContainer *genes } } - return HasPartialQuorum(state.CommitteeMember, rc), rc + return HasPartialQuorum(state.Share, rc), rc } // hasReceivedProposalJustificationForLeadingRound returns @@ -136,7 +136,7 @@ func hasReceivedPartialQuorum(state *types.State, roundChangeMsgContainer *genes // if received round change msgs with prepare justification - returns the highest prepare justification round change msg and value to propose // (all the above considering the operator is a leader for the round func hasReceivedProposalJustificationForLeadingRound( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, instanceStartValue []byte, signedRoundChange *genesisspecqbft.SignedMessage, @@ -145,7 +145,7 @@ func hasReceivedProposalJustificationForLeadingRound( ) (*genesisspecqbft.SignedMessage, []byte, error) { roundChanges := roundChangeMsgContainer.MessagesForRound(signedRoundChange.Message.Round) // optimization, if no round change quorum can return false - if !HasQuorum(state.CommitteeMember, roundChanges) { + if !HasQuorum(state.Share, roundChanges) { return nil, nil, nil } @@ -181,7 +181,7 @@ func hasReceivedProposalJustificationForLeadingRound( // isProposalJustificationForLeadingRound - returns nil if we have a quorum of round change msgs and highest justified value for leading round func isProposalJustificationForLeadingRound( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, roundChangeMsg *genesisspecqbft.SignedMessage, roundChanges []*genesisspecqbft.SignedMessage, @@ -217,7 +217,7 @@ func isProposalJustificationForLeadingRound( // isReceivedProposalJustification - returns nil if we have a quorum of round change msgs and highest justified value func isReceivedProposalJustification( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, roundChanges, prepares []*genesisspecqbft.SignedMessage, newRound genesisspecqbft.Round, @@ -240,7 +240,7 @@ func isReceivedProposalJustification( } func validRoundChangeForData( - state *types.State, + state *genesisspecqbft.State, config qbft.IConfig, signedMsg *genesisspecqbft.SignedMessage, height genesisspecqbft.Height, @@ -261,7 +261,7 @@ func validRoundChangeForData( } if config.VerifySignatures() { - if err := types.VerifyByOperators(signedMsg.Signature, signedMsg, config.GetSignatureDomainType(), genesisspectypes.QBFTSignatureType, state.CommitteeMember.Committee); err != nil { + if err := types.VerifyByOperators(signedMsg.Signature, signedMsg, config.GetSignatureDomainType(), genesisspectypes.QBFTSignatureType, state.Share.Committee); err != nil { return errors.Wrap(err, "msg signature invalid") } } @@ -287,7 +287,7 @@ func validRoundChangeForData( state.Height, signedMsg.Message.DataRound, signedMsg.Message.Root, - state.CommitteeMember.Committee); err != nil { + state.Share.Committee); err != nil { return errors.Wrap(err, "round change justification invalid") } } @@ -296,7 +296,7 @@ func validRoundChangeForData( return errors.New("H(data) != root") } - if !HasQuorum(state.CommitteeMember, prepareMsgs) { + if !HasQuorum(state.Share, prepareMsgs) { return errors.New("no justifications quorum") } @@ -339,7 +339,7 @@ func minRound(roundChangeMsgs []*genesisspecqbft.SignedMessage) genesisspecqbft. return ret } -func getRoundChangeData(state *types.State, config qbft.IConfig, instanceStartValue []byte) (genesisspecqbft.Round, [32]byte, []byte, []*genesisspecqbft.SignedMessage, error) { +func getRoundChangeData(state *genesisspecqbft.State, config qbft.IConfig, instanceStartValue []byte) (genesisspecqbft.Round, [32]byte, []byte, []*genesisspecqbft.SignedMessage, error) { if state.LastPreparedRound != genesisspecqbft.NoRound && state.LastPreparedValue != nil { justifications, err := getRoundChangeJustification(state, config, state.PrepareContainer) if err != nil { @@ -370,7 +370,7 @@ RoundChange( getRoundChangeJustification(current) ) */ -func CreateRoundChange(state *types.State, config qbft.IConfig, newRound genesisspecqbft.Round, instanceStartValue []byte) (*genesisspecqbft.SignedMessage, error) { +func CreateRoundChange(state *genesisspecqbft.State, config qbft.IConfig, newRound genesisspecqbft.Round, instanceStartValue []byte) (*genesisspecqbft.SignedMessage, error) { round, root, fullData, justifications, err := getRoundChangeData(state, config, instanceStartValue) if err != nil { return nil, errors.Wrap(err, "could not generate round change data") @@ -390,7 +390,7 @@ func CreateRoundChange(state *types.State, config qbft.IConfig, newRound genesis DataRound: round, RoundChangeJustification: justificationsData, } - sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.CommitteeMember.SSVOperatorPubKey) + sig, err := config.GetSigner().SignRoot(msg, genesisspectypes.QBFTSignatureType, state.Share.SharePubKey) if err != nil { return nil, errors.Wrap(err, "failed signing round change msg") } diff --git a/protocol/genesis/qbft/storage/ibft_store.go b/protocol/genesis/qbft/storage/ibft_store.go index 26efd46e30..1d44b4fa91 100644 --- a/protocol/genesis/qbft/storage/ibft_store.go +++ b/protocol/genesis/qbft/storage/ibft_store.go @@ -6,12 +6,11 @@ import ( "go.uber.org/zap" genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" - "github.com/ssvlabs/ssv/protocol/genesis/types" ) // StoredInstance contains instance state alongside with a decided message (aggregated commits). type StoredInstance struct { - State *types.State + State *genesisspecqbft.State DecidedMessage *genesisspecqbft.SignedMessage } diff --git a/protocol/genesis/ssv/runner/compact.go b/protocol/genesis/ssv/runner/compact.go index 7035b6f395..7264c8782b 100644 --- a/protocol/genesis/ssv/runner/compact.go +++ b/protocol/genesis/ssv/runner/compact.go @@ -12,7 +12,7 @@ import ( // - Advanced a round: to discard messages from previous rounds. (otherwise it might grow indefinitely) func (b *BaseRunner) compactInstanceIfNeeded(msg *genesisspecqbft.SignedMessage) { if inst := b.QBFTController.StoredInstances.FindInstance(msg.Message.Height); inst != nil { - if controller.IsDecidedMsg(b.QBFTController.CommitteeMember, msg) || msg.Message.MsgType == genesisspecqbft.RoundChangeMsgType { + if controller.IsDecidedMsg(b.QBFTController.Share, msg) || msg.Message.MsgType == genesisspecqbft.RoundChangeMsgType { instance.Compact(inst.State, msg) } } diff --git a/protocol/genesis/ssv/validator/non_committee_validator.go b/protocol/genesis/ssv/validator/non_committee_validator.go index 43ca730118..80622c6d75 100644 --- a/protocol/genesis/ssv/validator/non_committee_validator.go +++ b/protocol/genesis/ssv/validator/non_committee_validator.go @@ -29,7 +29,26 @@ func NewNonCommitteeValidator(logger *zap.Logger, identifier genesisspectypes.Me Network: opts.Network, SignatureVerification: true, } - ctrl := qbftcontroller.NewController(identifier[:], opts.Operator, config, opts.FullNode) + + share := &genesisspectypes.Share{} + + share.OperatorID = opts.Operator.OperatorID + share.ValidatorPubKey = opts.SSVShare.Share.ValidatorPubKey[:] + share.SharePubKey = opts.SSVShare.Share.SharePubKey + share.Committee = make([]*genesisspectypes.Operator, len(opts.SSVShare.Share.Committee)) + for _, c := range opts.SSVShare.Share.Committee { + share.Committee = append(share.Committee, &genesisspectypes.Operator{ + OperatorID: c.Signer, + PubKey: c.SharePubKey, + }) + } + + share.Quorum = opts.Operator.GetQuorum() + share.DomainType = genesisspectypes.DomainType(opts.SSVShare.Share.DomainType) + share.FeeRecipientAddress = opts.SSVShare.Share.FeeRecipientAddress + share.Graffiti = opts.SSVShare.Share.Graffiti + + ctrl := qbftcontroller.NewController(identifier[:], share, config, opts.FullNode) ctrl.StoredInstances = make(qbftcontroller.InstanceContainer, 0, nonCommitteeInstanceContainerCapacity(opts.FullNode)) ctrl.NewDecidedHandler = opts.NewDecidedHandler if _, err := ctrl.LoadHighestInstance(identifier[:]); err != nil { diff --git a/protocol/genesis/types/crypto.go b/protocol/genesis/types/crypto.go index c3ceaad66c..2f96703f8e 100644 --- a/protocol/genesis/types/crypto.go +++ b/protocol/genesis/types/crypto.go @@ -7,7 +7,6 @@ import ( "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" @@ -33,7 +32,7 @@ func init() { // DeserializeBLSPublicKey function and bounded.CGO // // TODO: rethink this function and consider moving/refactoring it. -func VerifyByOperators(s genesisspectypes.Signature, data genesisspectypes.MessageSignature, domain genesisspectypes.DomainType, sigType genesisspectypes.SignatureType, operators []*types.Operator) error { +func VerifyByOperators(s genesisspectypes.Signature, data genesisspectypes.MessageSignature, domain genesisspectypes.DomainType, sigType genesisspectypes.SignatureType, operators []*genesisspectypes.Operator) error { MetricsSignaturesVerificationsGenesis.WithLabelValues().Inc() sign := &bls.Sign{} @@ -46,7 +45,7 @@ func VerifyByOperators(s genesisspectypes.Signature, data genesisspectypes.Messa found := false for _, n := range operators { if id == n.OperatorID { - pk, err := DeserializeBLSPublicKey(n.SSVOperatorPubKey) + pk, err := DeserializeBLSPublicKey(n.PubKey) if err != nil { return errors.Wrap(err, "failed to deserialize public key") } diff --git a/protocol/genesis/types/state.go b/protocol/genesis/types/state.go index 1aff0ada71..d5df6658cb 100644 --- a/protocol/genesis/types/state.go +++ b/protocol/genesis/types/state.go @@ -6,13 +6,12 @@ import ( "github.com/pkg/errors" genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" - genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" spectypes "github.com/ssvlabs/ssv-spec/types" ) // State is copied from spec with changed Share type State struct { - CommitteeMember *spectypes.CommitteeMember + Share *spectypes.Share ID []byte // instance Identifier Round genesisspecqbft.Round Height genesisspecqbft.Height @@ -47,13 +46,3 @@ func (s *State) Encode() ([]byte, error) { func (s *State) Decode(data []byte) error { return json.Unmarshal(data, &s) } - -func RoundRobinProposer(state *State, round genesisspecqbft.Round) genesisspectypes.OperatorID { - firstRoundIndex := 0 - if state.Height != genesisspecqbft.FirstHeight { - firstRoundIndex += int(state.Height) % len(state.CommitteeMember.Committee) - } - - index := (firstRoundIndex + int(round) - int(genesisspecqbft.FirstRound)) % len(state.CommitteeMember.Committee) - return state.CommitteeMember.Committee[index].OperatorID -} From b7ae42be733a924884afd19b267b306dbca04820 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Tue, 23 Jul 2024 18:19:17 +0200 Subject: [PATCH 2/8] add logs --- network/p2p/p2p_pubsub.go | 8 ++++++++ protocol/genesis/ssv/validator/msgqueue_consumer.go | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/network/p2p/p2p_pubsub.go b/network/p2p/p2p_pubsub.go index 4ecb3015ca..c487d4ac30 100644 --- a/network/p2p/p2p_pubsub.go +++ b/network/p2p/p2p_pubsub.go @@ -223,10 +223,18 @@ func (n *p2pNetwork) handlePubsubMessages(logger *zap.Logger) func(ctx context.C m, ok := msg.ValidatorData.(*queue.SSVMessage) if ok { decodedMsg = m + logger.With( + zap.String("pubKey", hex.EncodeToString(m.SSVMessage.MsgID.GetDutyExecutorID())), + zap.String("role", m.SSVMessage.MsgID.GetRoleType().String()), + ).Debug("handlePubsubMessages - alan") } else { m, ok := msg.ValidatorData.(*genesisqueue.GenesisSSVMessage) if ok { decodedMsg = m + logger.With( + zap.String("pubKey", hex.EncodeToString(m.SSVMessage.MsgID.GetPubKey())), + zap.String("role", m.SSVMessage.MsgID.GetRoleType().String()), + ).Debug("handlePubsubMessages - genesis") } } diff --git a/protocol/genesis/ssv/validator/msgqueue_consumer.go b/protocol/genesis/ssv/validator/msgqueue_consumer.go index 9ee8a0296c..502e70ed44 100644 --- a/protocol/genesis/ssv/validator/msgqueue_consumer.go +++ b/protocol/genesis/ssv/validator/msgqueue_consumer.go @@ -46,7 +46,7 @@ func (v *Validator) HandleMessage(logger *zap.Logger, msg *genesisqueue.GenesisS zap.String("msg_type", genesismessage.MsgTypeToString(msg.MsgType)), zap.String("msg_id", msgID)) } - // logger.Debug("📬 queue: pushed message", fields.MessageID(msg.MsgID), fields.MessageType(msg.MsgType)) + logger.Debug("📬 queue: pushed message", fields.MessageID(spectypes.MessageID(msg.MsgID)), fields.MessageType(spectypes.MsgType(msg.MsgType))) } else { logger.Error("❌ missing queue for role type", fields.GenesisRole(msg.MsgID.GetRoleType())) } From 675dfba5b150af409379ab70f8b41b5bd9ecee9b Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Tue, 23 Jul 2024 20:26:05 +0200 Subject: [PATCH 3/8] fix tests --- ibft/genesisstorage/store_test.go | 6 +-- ibft/genesisstorage/stores_test.go | 3 +- .../genesis/qbft/instance/compact_test.go | 46 +++++++++--------- protocol/genesis/qbft/testing/utils.go | 6 +-- protocol/genesis/types/state.go | 48 ------------------- 5 files changed, 28 insertions(+), 81 deletions(-) delete mode 100644 protocol/genesis/types/state.go diff --git a/ibft/genesisstorage/store_test.go b/ibft/genesisstorage/store_test.go index 4eee7d3ac5..9654597c66 100644 --- a/ibft/genesisstorage/store_test.go +++ b/ibft/genesisstorage/store_test.go @@ -24,7 +24,7 @@ func TestCleanInstances(t *testing.T) { generateInstance := func(id genesisspectypes.MessageID, h genesisspecqbft.Height) *genesisqbftstorage.StoredInstance { return &genesisqbftstorage.StoredInstance{ - State: &types.State{ + State: &genesisspecqbft.State{ ID: id[:], Round: 1, Height: h, @@ -96,7 +96,7 @@ func TestSaveAndFetchLastState(t *testing.T) { identifier := genesisspectypes.NewMsgID(types.GetDefaultDomain(), []byte("pk"), genesisspectypes.BNRoleAttester) instance := &genesisqbftstorage.StoredInstance{ - State: &types.State{ + State: &genesisspecqbft.State{ Share: nil, ID: identifier[:], Round: 1, @@ -134,7 +134,7 @@ func TestSaveAndFetchState(t *testing.T) { identifier := genesisspectypes.NewMsgID(types.GetDefaultDomain(), []byte("pk"), genesisspectypes.BNRoleAttester) instance := &genesisqbftstorage.StoredInstance{ - State: &types.State{ + State: &genesisspecqbft.State{ Share: nil, ID: identifier[:], Round: 1, diff --git a/ibft/genesisstorage/stores_test.go b/ibft/genesisstorage/stores_test.go index 9838343ca2..361686d335 100644 --- a/ibft/genesisstorage/stores_test.go +++ b/ibft/genesisstorage/stores_test.go @@ -9,7 +9,6 @@ import ( "github.com/ssvlabs/ssv/logging" genesisqbftstorage "github.com/ssvlabs/ssv/protocol/genesis/qbft/storage" - "github.com/ssvlabs/ssv/protocol/genesis/types" "github.com/ssvlabs/ssv/storage/basedb" "github.com/ssvlabs/ssv/storage/kv" ) @@ -39,7 +38,7 @@ func TestQBFTStores(t *testing.T) { id := []byte{1, 2, 3} qbftMap.Each(func(role genesisspectypes.BeaconRole, store genesisqbftstorage.QBFTStore) error { - return store.SaveInstance(&genesisqbftstorage.StoredInstance{State: &types.State{Height: 1, ID: id}}) + return store.SaveInstance(&genesisqbftstorage.StoredInstance{State: &genesisspecqbft.State{Height: 1, ID: id}}) }) instance, err := qbftMap.Get(genesisspectypes.BNRoleAttester).GetInstance(id, 1) diff --git a/protocol/genesis/qbft/instance/compact_test.go b/protocol/genesis/qbft/instance/compact_test.go index 49fb9477e2..683205a9b5 100644 --- a/protocol/genesis/qbft/instance/compact_test.go +++ b/protocol/genesis/qbft/instance/compact_test.go @@ -5,25 +5,23 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" - "github.com/ssvlabs/ssv/protocol/genesis/types" "github.com/stretchr/testify/require" ) var compactTests = []struct { name string - inputState *types.State + inputState *genesisspecqbft.State inputMsg *genesisspecqbft.SignedMessage - expected *types.State // if nil, expected to be equal to input + expected *genesisspecqbft.State // if nil, expected to be equal to input }{ { name: "empty", - inputState: &types.State{}, + inputState: &genesisspecqbft.State{}, expected: nil, }, { name: "empty but not nil", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 1, ProposeContainer: &genesisspecqbft.MsgContainer{}, PrepareContainer: &genesisspecqbft.MsgContainer{}, @@ -34,7 +32,7 @@ var compactTests = []struct { }, { name: "nothing to compact", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 1, ProposeContainer: mockContainer(1, 2), PrepareContainer: mockContainer(1, 2), @@ -45,7 +43,7 @@ var compactTests = []struct { }, { name: "compact non-decided with previous rounds", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 2, ProposeContainer: mockContainer(1, 2), @@ -53,7 +51,7 @@ var compactTests = []struct { CommitContainer: mockContainer(1, 2), RoundChangeContainer: mockContainer(1, 2), }, - expected: &types.State{ + expected: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 2, ProposeContainer: mockContainer(2), @@ -64,7 +62,7 @@ var compactTests = []struct { }, { name: "compact non-decided with previous rounds except for prepared", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 1, ProposeContainer: mockContainer(1, 2), @@ -72,7 +70,7 @@ var compactTests = []struct { CommitContainer: mockContainer(1, 2), RoundChangeContainer: mockContainer(1, 2), }, - expected: &types.State{ + expected: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 1, ProposeContainer: mockContainer(2), @@ -83,12 +81,12 @@ var compactTests = []struct { }, { name: "compact quorum decided with previous rounds", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 3, LastPreparedRound: 3, Decided: true, - Share: &spectypes.CommitteeMember{ - Committee: make([]*spectypes.Operator, 4), + Share: &genesisspectypes.Share{ + Committee: make([]*genesisspectypes.Operator, 4), }, ProposeContainer: mockContainer(1, 2, 3, 4), PrepareContainer: mockContainer(1, 2, 3, 4), @@ -98,12 +96,12 @@ var compactTests = []struct { inputMsg: &genesisspecqbft.SignedMessage{ Signers: []genesisspectypes.OperatorID{1, 2, 3}, }, - expected: &types.State{ + expected: &genesisspecqbft.State{ Round: 3, LastPreparedRound: 3, Decided: true, - Share: &spectypes.CommitteeMember{ - Committee: make([]*spectypes.Operator, 4), + Share: &genesisspectypes.Share{ + Committee: make([]*genesisspectypes.Operator, 4), }, ProposeContainer: mockContainer(), PrepareContainer: mockContainer(), @@ -113,12 +111,12 @@ var compactTests = []struct { }, { name: "compact whole committee decided with previous rounds", - inputState: &types.State{ + inputState: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 2, Decided: true, - Share: &spectypes.CommitteeMember{ - Committee: make([]*spectypes.Operator, 4), + Share: &genesisspectypes.Share{ + Committee: make([]*genesisspectypes.Operator, 4), }, ProposeContainer: mockContainer(1, 2, 3, 4), PrepareContainer: mockContainer(1, 2, 3, 4), @@ -128,12 +126,12 @@ var compactTests = []struct { inputMsg: &genesisspecqbft.SignedMessage{ Signers: []genesisspectypes.OperatorID{1, 2, 3, 4}, }, - expected: &types.State{ + expected: &genesisspecqbft.State{ Round: 2, LastPreparedRound: 2, Decided: true, - Share: &spectypes.CommitteeMember{ - Committee: make([]*spectypes.Operator, 4), + Share: &genesisspectypes.Share{ + Committee: make([]*genesisspectypes.Operator, 4), }, ProposeContainer: mockContainer(), PrepareContainer: mockContainer(), @@ -150,7 +148,7 @@ func TestCompact(t *testing.T) { require.NoError(t, err) if tt.expected == nil { - tt.expected = &types.State{} + tt.expected = &genesisspecqbft.State{} require.NoError(t, tt.expected.Decode(inputStateBefore)) } diff --git a/protocol/genesis/qbft/testing/utils.go b/protocol/genesis/qbft/testing/utils.go index 8ee7f14bb8..74aeb5947b 100644 --- a/protocol/genesis/qbft/testing/utils.go +++ b/protocol/genesis/qbft/testing/utils.go @@ -6,7 +6,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" "github.com/ssvlabs/ssv-spec-pre-cc/types/testingutils" - spectypes "github.com/ssvlabs/ssv-spec/types" "github.com/pkg/errors" "go.uber.org/zap" @@ -14,7 +13,6 @@ import ( "github.com/ssvlabs/ssv/protocol/genesis/qbft" "github.com/ssvlabs/ssv/protocol/genesis/qbft/controller" "github.com/ssvlabs/ssv/protocol/genesis/qbft/roundtimer" - genesisrunner "github.com/ssvlabs/ssv/protocol/genesis/ssv/runner" ) var TestingConfig = func(logger *zap.Logger, keySet *testingutils.TestKeySet, role genesisspectypes.BeaconRole) *qbft.Config { @@ -33,7 +31,7 @@ var TestingConfig = func(logger *zap.Logger, keySet *testingutils.TestKeySet, ro } return nil }, - ProposerF: func(state *genesisrunner.State, round genesisspecqbft.Round) genesisspectypes.OperatorID { + ProposerF: func(state *genesisspecqbft.State, round genesisspecqbft.Round) genesisspectypes.OperatorID { return 1 }, Storage: TestingStores(logger).Get(role), @@ -81,7 +79,7 @@ var baseInstance = func(share *genesisspectypes.Share, keySet *testingutils.Test func NewTestingQBFTController( identifier []byte, - share *spectypes.Share, + share *genesisspectypes.Share, config qbft.IConfig, fullNode bool, ) *controller.Controller { diff --git a/protocol/genesis/types/state.go b/protocol/genesis/types/state.go deleted file mode 100644 index d5df6658cb..0000000000 --- a/protocol/genesis/types/state.go +++ /dev/null @@ -1,48 +0,0 @@ -package types - -import ( - "crypto/sha256" - "encoding/json" - - "github.com/pkg/errors" - genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" -) - -// State is copied from spec with changed Share -type State struct { - Share *spectypes.Share - ID []byte // instance Identifier - Round genesisspecqbft.Round - Height genesisspecqbft.Height - LastPreparedRound genesisspecqbft.Round - LastPreparedValue []byte - ProposalAcceptedForCurrentRound *genesisspecqbft.SignedMessage - Decided bool - DecidedValue []byte - - ProposeContainer *genesisspecqbft.MsgContainer - PrepareContainer *genesisspecqbft.MsgContainer - CommitContainer *genesisspecqbft.MsgContainer - RoundChangeContainer *genesisspecqbft.MsgContainer -} - -// GetRoot returns the state's deterministic root -func (s *State) GetRoot() ([32]byte, error) { - marshaledRoot, err := s.Encode() - if err != nil { - return [32]byte{}, errors.Wrap(err, "could not encode state") - } - ret := sha256.Sum256(marshaledRoot) - return ret, nil -} - -// Encode returns a msg encoded bytes or error -func (s *State) Encode() ([]byte, error) { - return json.Marshal(s) -} - -// Decode returns error if decoding failed -func (s *State) Decode(data []byte) error { - return json.Unmarshal(data, &s) -} From 0ec302fc33743b6f26e9566308ed06ca55bd0f45 Mon Sep 17 00:00:00 2001 From: y0sher Date: Tue, 23 Jul 2024 22:04:08 +0300 Subject: [PATCH 4/8] try to use old share --- operator/validator/controller.go | 14 +++++++------- protocol/genesis/ssv/runner/aggregator.go | 6 ++---- protocol/genesis/ssv/runner/attester.go | 5 ++--- protocol/genesis/ssv/runner/proposer.go | 5 ++--- protocol/genesis/ssv/runner/runner.go | 5 ++--- protocol/genesis/ssv/runner/runner_signatures.go | 6 +++--- protocol/genesis/ssv/runner/sync_committee.go | 5 ++--- .../ssv/runner/sync_committee_aggregator.go | 5 ++--- .../genesis/ssv/runner/validator_registration.go | 5 ++--- protocol/genesis/ssv/runner/voluntary_exit.go | 5 ++--- protocol/genesis/ssv/validator/startup.go | 3 ++- 11 files changed, 28 insertions(+), 36 deletions(-) diff --git a/operator/validator/controller.go b/operator/validator/controller.go index 92be62d2a2..b70079a1e3 100644 --- a/operator/validator/controller.go +++ b/operator/validator/controller.go @@ -1512,29 +1512,29 @@ func SetupGenesisRunners(ctx context.Context, logger *zap.Logger, options valida case genesisspectypes.BNRoleAttester: valCheck := genesisspecssv.AttesterValueCheckF(options.GenesisOptions.Signer, genesisBeaconNetwork, options.SSVShare.Share.ValidatorPubKey[:], options.SSVShare.BeaconMetadata.Index, options.SSVShare.SharePubKey) qbftCtrl := buildController(genesisspectypes.BNRoleAttester, valCheck) - runners[role] = genesisrunner.NewAttesterRunnner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, valCheck, 0, options.Operator.OperatorID) + runners[role] = genesisrunner.NewAttesterRunnner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, valCheck, 0, options.Operator.OperatorID) case genesisspectypes.BNRoleProposer: proposedValueCheck := genesisspecssv.ProposerValueCheckF(options.GenesisOptions.Signer, genesisBeaconNetwork, options.SSVShare.Share.ValidatorPubKey[:], options.SSVShare.BeaconMetadata.Index, options.SSVShare.SharePubKey) qbftCtrl := buildController(genesisspectypes.BNRoleProposer, proposedValueCheck) - runners[role] = genesisrunner.NewProposerRunner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, proposedValueCheck, 0, options.Operator.OperatorID) + runners[role] = genesisrunner.NewProposerRunner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, proposedValueCheck, 0, options.Operator.OperatorID) runners[role].(*genesisrunner.ProposerRunner).ProducesBlindedBlocks = options.BuilderProposals // apply blinded block flag case genesisspectypes.BNRoleAggregator: aggregatorValueCheckF := genesisspecssv.AggregatorValueCheckF(options.GenesisOptions.Signer, genesisBeaconNetwork, options.SSVShare.Share.ValidatorPubKey[:], options.SSVShare.BeaconMetadata.Index) qbftCtrl := buildController(genesisspectypes.BNRoleAggregator, aggregatorValueCheckF) - runners[role] = genesisrunner.NewAggregatorRunner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, aggregatorValueCheckF, 0, options.Operator.OperatorID) + runners[role] = genesisrunner.NewAggregatorRunner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, aggregatorValueCheckF, 0, options.Operator.OperatorID) case genesisspectypes.BNRoleSyncCommittee: syncCommitteeValueCheckF := genesisspecssv.SyncCommitteeValueCheckF(options.GenesisOptions.Signer, genesisBeaconNetwork, options.SSVShare.ValidatorPubKey[:], options.SSVShare.BeaconMetadata.Index) qbftCtrl := buildController(genesisspectypes.BNRoleSyncCommittee, syncCommitteeValueCheckF) - runners[role] = genesisrunner.NewSyncCommitteeRunner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, syncCommitteeValueCheckF, 0, options.Operator.OperatorID) + runners[role] = genesisrunner.NewSyncCommitteeRunner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, syncCommitteeValueCheckF, 0, options.Operator.OperatorID) case genesisspectypes.BNRoleSyncCommitteeContribution: syncCommitteeContributionValueCheckF := genesisspecssv.SyncCommitteeContributionValueCheckF(options.GenesisOptions.Signer, genesisBeaconNetwork, options.SSVShare.Share.ValidatorPubKey[:], options.SSVShare.BeaconMetadata.Index) qbftCtrl := buildController(genesisspectypes.BNRoleSyncCommitteeContribution, syncCommitteeContributionValueCheckF) - runners[role] = genesisrunner.NewSyncCommitteeAggregatorRunner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, syncCommitteeContributionValueCheckF, 0, options.Operator.OperatorID) + runners[role] = genesisrunner.NewSyncCommitteeAggregatorRunner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, syncCommitteeContributionValueCheckF, 0, options.Operator.OperatorID) case genesisspectypes.BNRoleValidatorRegistration: qbftCtrl := buildController(genesisspectypes.BNRoleValidatorRegistration, nil) - runners[role] = genesisrunner.NewValidatorRegistrationRunner(genesisBeaconNetwork, &options.SSVShare.Share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, options.Operator.OperatorID) + runners[role] = genesisrunner.NewValidatorRegistrationRunner(genesisBeaconNetwork, share, qbftCtrl, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, options.Operator.OperatorID) case genesisspectypes.BNRoleVoluntaryExit: - runners[role] = genesisrunner.NewVoluntaryExitRunner(genesisBeaconNetwork, &options.SSVShare.Share, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, options.Operator.OperatorID) + runners[role] = genesisrunner.NewVoluntaryExitRunner(genesisBeaconNetwork, share, options.Beacon, options.GenesisOptions.Network, options.GenesisOptions.Signer, options.Operator.OperatorID) } } return runners diff --git a/protocol/genesis/ssv/runner/aggregator.go b/protocol/genesis/ssv/runner/aggregator.go index 60a13909ee..46beb1f94d 100644 --- a/protocol/genesis/ssv/runner/aggregator.go +++ b/protocol/genesis/ssv/runner/aggregator.go @@ -10,8 +10,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" - "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -35,7 +33,7 @@ var _ Runner = &AggregatorRunner{} func NewAggregatorRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -306,7 +304,7 @@ func (r *AggregatorRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *AggregatorRunner) GetShare() *spectypes.Share { +func (r *AggregatorRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/attester.go b/protocol/genesis/ssv/runner/attester.go index b20cbbee8d..a96d0ed241 100644 --- a/protocol/genesis/ssv/runner/attester.go +++ b/protocol/genesis/ssv/runner/attester.go @@ -14,7 +14,6 @@ import ( genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -38,7 +37,7 @@ type AttesterRunner struct { func NewAttesterRunnner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -265,7 +264,7 @@ func (r *AttesterRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *AttesterRunner) GetShare() *spectypes.Share { +func (r *AttesterRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/proposer.go b/protocol/genesis/ssv/runner/proposer.go index 97f799de11..1e5e8a370c 100644 --- a/protocol/genesis/ssv/runner/proposer.go +++ b/protocol/genesis/ssv/runner/proposer.go @@ -18,7 +18,6 @@ import ( genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/attestantio/go-eth2-client/spec" @@ -45,7 +44,7 @@ type ProposerRunner struct { func NewProposerRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -378,7 +377,7 @@ func (r *ProposerRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *ProposerRunner) GetShare() *spectypes.Share { +func (r *ProposerRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/runner.go b/protocol/genesis/ssv/runner/runner.go index 323de614f3..fa546699fa 100644 --- a/protocol/genesis/ssv/runner/runner.go +++ b/protocol/genesis/ssv/runner/runner.go @@ -9,7 +9,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/protocol/genesis/qbft/controller" @@ -51,7 +50,7 @@ type Runner interface { type BaseRunner struct { mtx sync.RWMutex State *State - Share *spectypes.Share + Share *genesisspectypes.Share QBFTController *controller.Controller BeaconNetwork genesisspectypes.BeaconNetwork BeaconRoleType genesisspectypes.BeaconRole @@ -82,7 +81,7 @@ func (b *BaseRunner) baseSetupForNewDuty(duty *genesisspectypes.Duty, quorum uin func NewBaseRunner( state *State, - share *spectypes.Share, + share *genesisspectypes.Share, controller *controller.Controller, beaconNetwork genesisspectypes.BeaconNetwork, beaconRoleType genesisspectypes.BeaconRole, diff --git a/protocol/genesis/ssv/runner/runner_signatures.go b/protocol/genesis/ssv/runner/runner_signatures.go index e2465ca3f3..bb0ed4d744 100644 --- a/protocol/genesis/ssv/runner/runner_signatures.go +++ b/protocol/genesis/ssv/runner/runner_signatures.go @@ -63,7 +63,7 @@ func (b *BaseRunner) validatePartialSigMsgForSlot( // Check if signer is in committee signerInCommittee := false for _, operator := range b.Share.Committee { - if operator.Signer == signedMsg.Signer { + if operator.OperatorID == signedMsg.Signer { signerInCommittee = true break } @@ -79,8 +79,8 @@ func (b *BaseRunner) verifyBeaconPartialSignature(signer uint64, signature genes types.MetricsSignaturesVerificationsGenesis.WithLabelValues().Inc() for _, n := range b.Share.Committee { - if n.Signer == signer { - pk, err := types.DeserializeBLSPublicKey(n.SharePubKey[:]) + if n.OperatorID == signer { + pk, err := types.DeserializeBLSPublicKey(n.GetPublicKey()[:]) if err != nil { return errors.Wrap(err, "could not deserialized pk") } diff --git a/protocol/genesis/ssv/runner/sync_committee.go b/protocol/genesis/ssv/runner/sync_committee.go index fc0a634e6c..fc846cf8fb 100644 --- a/protocol/genesis/ssv/runner/sync_committee.go +++ b/protocol/genesis/ssv/runner/sync_committee.go @@ -13,7 +13,6 @@ import ( genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" specqbft "github.com/ssvlabs/ssv-spec/qbft" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -36,7 +35,7 @@ type SyncCommitteeRunner struct { func NewSyncCommitteeRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -240,7 +239,7 @@ func (r *SyncCommitteeRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *SyncCommitteeRunner) GetShare() *spectypes.Share { +func (r *SyncCommitteeRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/sync_committee_aggregator.go b/protocol/genesis/ssv/runner/sync_committee_aggregator.go index fb7964cd97..aa2edc05e0 100644 --- a/protocol/genesis/ssv/runner/sync_committee_aggregator.go +++ b/protocol/genesis/ssv/runner/sync_committee_aggregator.go @@ -12,7 +12,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/protocol/genesis/qbft/controller" @@ -34,7 +33,7 @@ type SyncCommitteeAggregatorRunner struct { func NewSyncCommitteeAggregatorRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -411,7 +410,7 @@ func (r *SyncCommitteeAggregatorRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *SyncCommitteeAggregatorRunner) GetShare() *spectypes.Share { +func (r *SyncCommitteeAggregatorRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/validator_registration.go b/protocol/genesis/ssv/runner/validator_registration.go index c09ed34829..1da86b9157 100644 --- a/protocol/genesis/ssv/runner/validator_registration.go +++ b/protocol/genesis/ssv/runner/validator_registration.go @@ -12,7 +12,6 @@ import ( genesisqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -35,7 +34,7 @@ type ValidatorRegistrationRunner struct { func NewValidatorRegistrationRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, qbftController *controller.Controller, beacon beacon.BeaconNode, network genesisspecssv.Network, @@ -193,7 +192,7 @@ func (r *ValidatorRegistrationRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *ValidatorRegistrationRunner) GetShare() *spectypes.Share { +func (r *ValidatorRegistrationRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/runner/voluntary_exit.go b/protocol/genesis/ssv/runner/voluntary_exit.go index 53a3068e43..aa2d125dca 100644 --- a/protocol/genesis/ssv/runner/voluntary_exit.go +++ b/protocol/genesis/ssv/runner/voluntary_exit.go @@ -11,7 +11,6 @@ import ( genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspecssv "github.com/ssvlabs/ssv-spec-pre-cc/ssv" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" - spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" "github.com/ssvlabs/ssv/logging/fields" @@ -36,7 +35,7 @@ type VoluntaryExitRunner struct { func NewVoluntaryExitRunner( beaconNetwork genesisspectypes.BeaconNetwork, - share *spectypes.Share, + share *genesisspectypes.Share, beacon beacon.BeaconNode, network genesisspecssv.Network, signer genesisspectypes.KeyManager, @@ -207,7 +206,7 @@ func (r *VoluntaryExitRunner) GetBeaconNode() beacon.BeaconNode { return r.beacon } -func (r *VoluntaryExitRunner) GetShare() *spectypes.Share { +func (r *VoluntaryExitRunner) GetShare() *genesisspectypes.Share { return r.BaseRunner.Share } diff --git a/protocol/genesis/ssv/validator/startup.go b/protocol/genesis/ssv/validator/startup.go index 079e68a48d..7b7e4dbb41 100644 --- a/protocol/genesis/ssv/validator/startup.go +++ b/protocol/genesis/ssv/validator/startup.go @@ -1,6 +1,7 @@ package validator import ( + "github.com/ssvlabs/ssv-spec/types" "sync/atomic" "github.com/pkg/errors" @@ -49,7 +50,7 @@ func (v *Validator) Start(logger *zap.Logger) (started bool, err error) { } } - if err := n.Subscribe(dutyRunner.GetBaseRunner().Share.ValidatorPubKey); err != nil { + if err := n.Subscribe(types.ValidatorPK(dutyRunner.GetBaseRunner().Share.ValidatorPubKey)); err != nil { return true, err } go v.StartQueueConsumer(logger, identifier, v.ProcessMessage) From 20ac555e98392ac6631c0144e8922f3f85aac33b Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Wed, 24 Jul 2024 10:03:30 +0200 Subject: [PATCH 5/8] fix tests --- protocol/genesis/types/share.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 protocol/genesis/types/share.go diff --git a/protocol/genesis/types/share.go b/protocol/genesis/types/share.go new file mode 100644 index 0000000000..8d20eeb26f --- /dev/null +++ b/protocol/genesis/types/share.go @@ -0,0 +1,26 @@ +package types + +import ( + genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" + spectypes "github.com/ssvlabs/ssv-spec/types" +) + +func ConvertToGenesisShare(share *spectypes.Share, operator *spectypes.CommitteeMember) *genesisspectypes.Share { + genesisShare := &genesisspectypes.Share{} + + genesisShare.OperatorID = operator.OperatorID + genesisShare.ValidatorPubKey = share.ValidatorPubKey[:] + genesisShare.SharePubKey = share.SharePubKey + genesisShare.Committee = make([]*genesisspectypes.Operator, 0, len(share.Committee)) + for _, c := range share.Committee { + genesisShare.Committee = append(genesisShare.Committee, &genesisspectypes.Operator{ + OperatorID: c.Signer, + PubKey: c.SharePubKey, + }) + } + genesisShare.Quorum = operator.GetQuorum() + genesisShare.DomainType = genesisspectypes.DomainType(share.DomainType) + genesisShare.FeeRecipientAddress = share.FeeRecipientAddress + genesisShare.Graffiti = share.Graffiti + return genesisShare +} From 95a209a044ad94857ebc3d03ba1d252896a826f7 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Wed, 24 Jul 2024 10:22:20 +0200 Subject: [PATCH 6/8] fix share convertion --- operator/validator/controller.go | 18 +---- operator/validator/controller_test.go | 13 ++-- operator/validator/mocks/validator_map.go | 2 +- operator/validator/router_test.go | 2 +- .../genesis/qbft/controller/types_test.go | 73 +++++++++---------- .../ssv/queue/message_prioritizer_test.go | 8 +- protocol/genesis/ssv/queue/queue_test.go | 12 +-- protocol/genesis/types/crypto.go | 4 +- protocol/genesis/types/share.go | 20 ++--- 9 files changed, 69 insertions(+), 83 deletions(-) diff --git a/operator/validator/controller.go b/operator/validator/controller.go index b70079a1e3..e733738b46 100644 --- a/operator/validator/controller.go +++ b/operator/validator/controller.go @@ -1461,23 +1461,7 @@ func SetupGenesisRunners(ctx context.Context, logger *zap.Logger, options valida genesisspectypes.BNRoleVoluntaryExit, } - share := &genesisspectypes.Share{} - - share.OperatorID = options.Operator.OperatorID - share.ValidatorPubKey = options.SSVShare.Share.ValidatorPubKey[:] - share.SharePubKey = options.SSVShare.Share.SharePubKey - share.Committee = make([]*genesisspectypes.Operator, len(options.SSVShare.Share.Committee)) - for _, c := range options.SSVShare.Share.Committee { - share.Committee = append(share.Committee, &genesisspectypes.Operator{ - OperatorID: c.Signer, - PubKey: c.SharePubKey, - }) - } - - share.Quorum = options.Operator.GetQuorum() - share.DomainType = genesisspectypes.DomainType(options.SSVShare.Share.DomainType) - share.FeeRecipientAddress = options.SSVShare.Share.FeeRecipientAddress - share.Graffiti = options.SSVShare.Share.Graffiti + share := genesisssvtypes.ConvertToGenesisShare(&options.SSVShare.Share, options.Operator) buildController := func(role genesisspectypes.BeaconRole, valueCheckF genesisspecqbft.ProposedValueCheckF) *genesisqbftcontroller.Controller { config := &genesisqbft.Config{ diff --git a/operator/validator/controller_test.go b/operator/validator/controller_test.go index 3925debfcf..aaa3d1a589 100644 --- a/operator/validator/controller_test.go +++ b/operator/validator/controller_test.go @@ -27,6 +27,7 @@ import ( genesisibftstorage "github.com/ssvlabs/ssv/ibft/genesisstorage" ibftstorage "github.com/ssvlabs/ssv/ibft/storage" "github.com/ssvlabs/ssv/logging" + "github.com/ssvlabs/ssv/network" "github.com/ssvlabs/ssv/networkconfig" operatordatastore "github.com/ssvlabs/ssv/operator/datastore" "github.com/ssvlabs/ssv/operator/keys" @@ -280,7 +281,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { var wg sync.WaitGroup - ctr.messageWorker.UseHandler(func(msg *queue.DecodedSSVMessage) error { + ctr.messageWorker.UseHandler(func(msg network.SSVMessageInterface) error { wg.Done() return nil }) @@ -289,7 +290,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { identifier := spectypes.NewMsgID(networkconfig.TestNetwork.DomainType(), []byte("pk"), spectypes.RoleCommittee) - ctr.messageRouter.Route(context.TODO(), &queue.DecodedSSVMessage{ + ctr.messageRouter.Route(context.TODO(), &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ // checks that not process unnecessary message MsgType: spectypes.SSVConsensusMsgType, MsgID: identifier, @@ -297,7 +298,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { }, }) - ctr.messageRouter.Route(context.TODO(), &queue.DecodedSSVMessage{ + ctr.messageRouter.Route(context.TODO(), &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ // checks that not process unnecessary message MsgType: spectypes.SSVConsensusMsgType, MsgID: identifier, @@ -305,7 +306,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { }, }) - ctr.messageRouter.Route(context.TODO(), &queue.DecodedSSVMessage{ + ctr.messageRouter.Route(context.TODO(), &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ // checks that not process unnecessary message MsgType: message.SSVSyncMsgType, MsgID: identifier, @@ -313,7 +314,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { }, }) - ctr.messageRouter.Route(context.TODO(), &queue.DecodedSSVMessage{ + ctr.messageRouter.Route(context.TODO(), &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ MsgType: spectypes.SSVPartialSignatureMsgType, MsgID: identifier, @@ -321,7 +322,7 @@ func TestHandleNonCommitteeMessages(t *testing.T) { }, }) - ctr.messageRouter.Route(context.TODO(), &queue.DecodedSSVMessage{ + ctr.messageRouter.Route(context.TODO(), &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ MsgType: spectypes.SSVPartialSignatureMsgType, MsgID: identifier, diff --git a/operator/validator/mocks/validator_map.go b/operator/validator/mocks/validator_map.go index 3154f20e44..e72b9255a1 100644 --- a/operator/validator/mocks/validator_map.go +++ b/operator/validator/mocks/validator_map.go @@ -52,7 +52,7 @@ func (mr *MockValidatorMockRecorder) GetShare() *gomock.Call { } // ProcessMessage mocks base method. -func (m *MockValidator) ProcessMessage(logger *zap.Logger, msg *queue.DecodedSSVMessage) error { +func (m *MockValidator) ProcessMessage(logger *zap.Logger, msg *queue.SSVMessage) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ProcessMessage", logger, msg) ret0, _ := ret[0].(error) diff --git a/operator/validator/router_test.go b/operator/validator/router_test.go index 9dc72beeb7..0b494b6cf1 100644 --- a/operator/validator/router_test.go +++ b/operator/validator/router_test.go @@ -41,7 +41,7 @@ func TestRouter(t *testing.T) { }() for i := 0; i < expectedCount; i++ { - msg := &queue.DecodedSSVMessage{ + msg := &queue.SSVMessage{ SSVMessage: &spectypes.SSVMessage{ MsgType: spectypes.MsgType(i % 3), MsgID: spectypes.NewMsgID(networkconfig.TestNetwork.DomainType(), []byte{1, 1, 1, 1, 1}, spectypes.RoleCommittee), diff --git a/protocol/genesis/qbft/controller/types_test.go b/protocol/genesis/qbft/controller/types_test.go index e4ee5db222..79e3405842 100644 --- a/protocol/genesis/qbft/controller/types_test.go +++ b/protocol/genesis/qbft/controller/types_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/ssvlabs/ssv/protocol/genesis/qbft/instance" - "github.com/ssvlabs/ssv/protocol/genesis/types" genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" "github.com/stretchr/testify/require" @@ -14,9 +13,9 @@ import ( func TestInstances_FindInstance(t *testing.T) { i := InstanceContainer{ - &instance.Instance{State: &types.State{Height: 1}}, - &instance.Instance{State: &types.State{Height: 2}}, - &instance.Instance{State: &types.State{Height: 3}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 2}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 3}}, } t.Run("find 1", func(t *testing.T) { @@ -34,20 +33,20 @@ func TestInstances_AddNewInstance(t *testing.T) { t.Run("add to full", func(t *testing.T) { i := append( make(InstanceContainer, 0, 5), - &instance.Instance{State: &types.State{Height: 1}}, - &instance.Instance{State: &types.State{Height: 2}}, - &instance.Instance{State: &types.State{Height: 3}}, - &instance.Instance{State: &types.State{Height: 4}}, - &instance.Instance{State: &types.State{Height: 5}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 2}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 3}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 4}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 5}}, ) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 6}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 6}}) requireHeights(t, i, 6, 1, 2, 3, 4) }) t.Run("add to empty", func(t *testing.T) { i := make(InstanceContainer, 0, 5) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 1}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 1}}) require.EqualValues(t, 1, i[0].State.Height) require.Len(t, i, 1) @@ -56,11 +55,11 @@ func TestInstances_AddNewInstance(t *testing.T) { t.Run("add to semi full", func(t *testing.T) { i := append( make(InstanceContainer, 0, 5), - &instance.Instance{State: &types.State{Height: 1}}, - &instance.Instance{State: &types.State{Height: 2}}, - &instance.Instance{State: &types.State{Height: 3}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 2}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 3}}, ) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 4}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 4}}) requireHeights(t, i, 4, 1, 2, 3) }) @@ -68,13 +67,13 @@ func TestInstances_AddNewInstance(t *testing.T) { t.Run("add to full with lower height", func(t *testing.T) { i := append( make(InstanceContainer, 0, 5), - &instance.Instance{State: &types.State{Height: 1}}, - &instance.Instance{State: &types.State{Height: 2}}, - &instance.Instance{State: &types.State{Height: 3}}, - &instance.Instance{State: &types.State{Height: 4}}, - &instance.Instance{State: &types.State{Height: 5}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 2}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 3}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 4}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 5}}, ) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 0}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 0}}) requireHeights(t, i, 1, 2, 3, 4, 5) }) @@ -82,13 +81,13 @@ func TestInstances_AddNewInstance(t *testing.T) { t.Run("add to full with higher height", func(t *testing.T) { i := append( make(InstanceContainer, 0, 5), - &instance.Instance{State: &types.State{Height: 1}}, - &instance.Instance{State: &types.State{Height: 2}}, - &instance.Instance{State: &types.State{Height: 3}}, - &instance.Instance{State: &types.State{Height: 4}}, - &instance.Instance{State: &types.State{Height: 5}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 2}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 3}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 4}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 5}}, ) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 6}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 6}}) requireHeights(t, i, 6, 1, 2, 3, 4) }) @@ -96,16 +95,16 @@ func TestInstances_AddNewInstance(t *testing.T) { t.Run("add to semi-full with higher height", func(t *testing.T) { i := append( make(InstanceContainer, 0, 5), - &instance.Instance{State: &types.State{Height: 9}}, - &instance.Instance{State: &types.State{Height: 7}}, - &instance.Instance{State: &types.State{Height: 5}}, - &instance.Instance{State: &types.State{Height: 1}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 9}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 7}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 5}}, + &instance.Instance{State: &genesisspecqbft.State{Height: 1}}, ) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 4}}) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 3}}) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 6}}) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 8}}) - i.addNewInstance(&instance.Instance{State: &types.State{Height: 8}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 4}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 3}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 6}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 8}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: 8}}) requireHeights(t, i, 9, 8, 8, 7, 6) }) @@ -122,7 +121,7 @@ func TestInstances_AddNewInstance(t *testing.T) { numberOfRandomHeights := 100 for _, height := range rand.Perm(numberOfRandomHeights) { // Add height to InstanceContainer. - i.addNewInstance(&instance.Instance{State: &types.State{Height: genesisspecqbft.Height(height)}}) + i.addNewInstance(&instance.Instance{State: &genesisspecqbft.State{Height: genesisspecqbft.Height(height)}}) // Add height to mirror. mirror = append(mirror, genesisspecqbft.Height(height)) diff --git a/protocol/genesis/ssv/queue/message_prioritizer_test.go b/protocol/genesis/ssv/queue/message_prioritizer_test.go index 0183768867..1d7cba038e 100644 --- a/protocol/genesis/ssv/queue/message_prioritizer_test.go +++ b/protocol/genesis/ssv/queue/message_prioritizer_test.go @@ -38,7 +38,7 @@ var messagePriorityTests = []struct { // 1.1. Events/ExecuteDuty mockExecuteDutyMessage{Slot: 62, Role: spectypes.BNRoleProposer}, // 1.2. Events/Timeout - mockTimeoutMessage{Height: 98, Role: spectypes.RunnerRole(spectypes.BNRoleProposer)}, + mockTimeoutMessage{Height: 98, Role: spectypes.BNRoleProposer}, // 2. Current height/slot: // 2.1. Consensus @@ -125,7 +125,7 @@ func TestMessagePrioritizer(t *testing.T) { messages := make(messageSlice, len(test.messages)) for i, m := range test.messages { var err error - messages[i], err = DecodeSignedSSVMessage(m.ssvMessage(test.state)) + messages[i], err = DecodeGenesisSignedSSVMessage(m.ssvMessage(test.state)) require.NoError(t, err) } @@ -158,7 +158,7 @@ type mockMessage interface { } type mockConsensusMessage struct { - Role spectypes.RunnerRole + Role spectypes.BeaconRole Type qbft.MessageType Decided bool Height qbft.Height @@ -213,7 +213,7 @@ func (m mockConsensusMessage) ssvMessage(state *State) *spectypes.SignedSSVMessa } type mockNonConsensusMessage struct { - Role spectypes.RunnerRole + Role spectypes.BeaconRole Type spectypes.PartialSigMsgType Slot phase0.Slot } diff --git a/protocol/genesis/ssv/queue/queue_test.go b/protocol/genesis/ssv/queue/queue_test.go index 6e0e9b0c9b..d05e4abac6 100644 --- a/protocol/genesis/ssv/queue/queue_test.go +++ b/protocol/genesis/ssv/queue/queue_test.go @@ -109,7 +109,7 @@ func TestPriorityQueue_Pop(t *testing.T) { queue := New(capacity) require.True(t, queue.Empty()) - msg, err := DecodeSignedSSVMessage(mockConsensusMessage{Height: 100, Type: qbft.PrepareMsgType}.ssvMessage(mockState)) + msg, err := DecodeGenesisSignedSSVMessage(mockConsensusMessage{Height: 100, Type: qbft.PrepareMsgType}.ssvMessage(mockState)) require.NoError(t, err) // Push messages. @@ -163,7 +163,7 @@ func TestPriorityQueue_Order(t *testing.T) { // Decode messages. messages := make(messageSlice, len(test.messages)) for i, m := range test.messages { - mm, err := DecodeSignedSSVMessage(m.ssvMessage(test.state)) + mm, err := DecodeGenesisSignedSSVMessage(m.ssvMessage(test.state)) require.NoError(t, err) messages[i] = mm } @@ -198,7 +198,7 @@ func TestWithMetrics(t *testing.T) { require.True(t, queue.Empty()) // Push 1 message. - msg, err := DecodeSignedSSVMessage(mockConsensusMessage{Height: 100, Type: qbft.PrepareMsgType}.ssvMessage(mockState)) + msg, err := DecodeGenesisSignedSSVMessage(mockConsensusMessage{Height: 100, Type: qbft.PrepareMsgType}.ssvMessage(mockState)) require.NoError(t, err) pushed := queue.TryPush(msg) require.True(t, pushed) @@ -236,7 +236,7 @@ func benchmarkPriorityQueueParallel(b *testing.B, factory func() Queue, lossy bo messages := make([]*GenesisSSVMessage, messageCount) for i := range messages { var err error - msg, err := DecodeSignedSSVMessage(mockConsensusMessage{Height: qbft.Height(rand.Intn(messageCount)), Type: qbft.PrepareMsgType}.ssvMessage(mockState)) + msg, err := DecodeGenesisSignedSSVMessage(mockConsensusMessage{Height: qbft.Height(rand.Intn(messageCount)), Type: qbft.PrepareMsgType}.ssvMessage(mockState)) require.NoError(b, err) messages[i] = msg } @@ -361,7 +361,7 @@ func BenchmarkPriorityQueue_Concurrent(b *testing.B) { for _, i := range rand.Perm(messageCount) { height := qbft.FirstHeight + qbft.Height(i) for _, t := range types { - decoded, err := DecodeSignedSSVMessage(mockConsensusMessage{Height: height, Type: t}.ssvMessage(mockState)) + decoded, err := DecodeGenesisSignedSSVMessage(mockConsensusMessage{Height: height, Type: t}.ssvMessage(mockState)) require.NoError(b, err) msgs <- decoded } @@ -414,7 +414,7 @@ func BenchmarkPriorityQueue_Concurrent(b *testing.B) { } func decodeAndPush(t require.TestingT, queue Queue, msg mockMessage, state *State) *GenesisSSVMessage { - decoded, err := DecodeSignedSSVMessage(msg.ssvMessage(state)) + decoded, err := DecodeGenesisSignedSSVMessage(msg.ssvMessage(state)) require.NoError(t, err) queue.Push(decoded) return decoded diff --git a/protocol/genesis/types/crypto.go b/protocol/genesis/types/crypto.go index 2f96703f8e..04aadef2d6 100644 --- a/protocol/genesis/types/crypto.go +++ b/protocol/genesis/types/crypto.go @@ -44,8 +44,8 @@ func VerifyByOperators(s genesisspectypes.Signature, data genesisspectypes.Messa for _, id := range data.GetSigners() { found := false for _, n := range operators { - if id == n.OperatorID { - pk, err := DeserializeBLSPublicKey(n.PubKey) + if id == n.GetID() { + pk, err := DeserializeBLSPublicKey(n.GetPublicKey()) if err != nil { return errors.Wrap(err, "failed to deserialize public key") } diff --git a/protocol/genesis/types/share.go b/protocol/genesis/types/share.go index 8d20eeb26f..fa9ddaf5a0 100644 --- a/protocol/genesis/types/share.go +++ b/protocol/genesis/types/share.go @@ -6,21 +6,23 @@ import ( ) func ConvertToGenesisShare(share *spectypes.Share, operator *spectypes.CommitteeMember) *genesisspectypes.Share { - genesisShare := &genesisspectypes.Share{} + genesisShare := &genesisspectypes.Share{ + OperatorID: operator.OperatorID, + ValidatorPubKey: share.ValidatorPubKey[:], // Ensure this is necessary; remove if ValidatorPubKey is already a slice. + SharePubKey: share.SharePubKey, + Committee: make([]*genesisspectypes.Operator, 0, len(share.Committee)), + Quorum: operator.GetQuorum(), + DomainType: genesisspectypes.DomainType(share.DomainType), + FeeRecipientAddress: share.FeeRecipientAddress, + Graffiti: share.Graffiti, + } - genesisShare.OperatorID = operator.OperatorID - genesisShare.ValidatorPubKey = share.ValidatorPubKey[:] - genesisShare.SharePubKey = share.SharePubKey - genesisShare.Committee = make([]*genesisspectypes.Operator, 0, len(share.Committee)) for _, c := range share.Committee { genesisShare.Committee = append(genesisShare.Committee, &genesisspectypes.Operator{ OperatorID: c.Signer, PubKey: c.SharePubKey, }) } - genesisShare.Quorum = operator.GetQuorum() - genesisShare.DomainType = genesisspectypes.DomainType(share.DomainType) - genesisShare.FeeRecipientAddress = share.FeeRecipientAddress - genesisShare.Graffiti = share.Graffiti + return genesisShare } From b8fc5471b8caedde03eba53c450f2d10f6f9fb94 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Wed, 24 Jul 2024 10:34:53 +0200 Subject: [PATCH 7/8] fix quorum --- protocol/genesis/types/share.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/protocol/genesis/types/share.go b/protocol/genesis/types/share.go index fa9ddaf5a0..2167c66abc 100644 --- a/protocol/genesis/types/share.go +++ b/protocol/genesis/types/share.go @@ -3,15 +3,18 @@ package types import ( genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" spectypes "github.com/ssvlabs/ssv-spec/types" + "github.com/ssvlabs/ssv/protocol/v2/types" ) func ConvertToGenesisShare(share *spectypes.Share, operator *spectypes.CommitteeMember) *genesisspectypes.Share { + q, pc := types.ComputeQuorumAndPartialQuorum(len(share.Committee)) genesisShare := &genesisspectypes.Share{ OperatorID: operator.OperatorID, ValidatorPubKey: share.ValidatorPubKey[:], // Ensure this is necessary; remove if ValidatorPubKey is already a slice. SharePubKey: share.SharePubKey, Committee: make([]*genesisspectypes.Operator, 0, len(share.Committee)), - Quorum: operator.GetQuorum(), + Quorum: q, + PartialQuorum: pc, DomainType: genesisspectypes.DomainType(share.DomainType), FeeRecipientAddress: share.FeeRecipientAddress, Graffiti: share.Graffiti, From f656d56a21699dbf2df3e541dd58a1fccdc2560c Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Wed, 24 Jul 2024 11:36:50 +0200 Subject: [PATCH 8/8] fix old types for signing --- ekm/genesis_adapter.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ekm/genesis_adapter.go b/ekm/genesis_adapter.go index f84ec7457b..877d8c2672 100644 --- a/ekm/genesis_adapter.go +++ b/ekm/genesis_adapter.go @@ -4,6 +4,7 @@ import ( "github.com/attestantio/go-eth2-client/spec/phase0" ssz "github.com/ferranbt/fastssz" "github.com/herumi/bls-eth-go-binary/bls" + "github.com/pkg/errors" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" spectypes "github.com/ssvlabs/ssv-spec/types" ) @@ -13,6 +14,37 @@ type GenesisKeyManagerAdapter struct { } func (k *GenesisKeyManagerAdapter) SignBeaconObject(obj ssz.HashRoot, domain phase0.Domain, pk []byte, domainType phase0.DomainType) (genesisspectypes.Signature, [32]byte, error) { + // Convert genesisspectypes to spectypes before passing on to KeyManager. + switch domainType { + case genesisspectypes.DomainAttester: + case genesisspectypes.DomainProposer: + case genesisspectypes.DomainVoluntaryExit: + case genesisspectypes.DomainAggregateAndProof: + case genesisspectypes.DomainSelectionProof: + data, ok := obj.(genesisspectypes.SSZUint64) + if !ok { + return nil, [32]byte{}, errors.New("could not cast obj to SSZUint64") + } + obj = spectypes.SSZUint64(data) + case genesisspectypes.DomainRandao: + data, ok := obj.(genesisspectypes.SSZUint64) + if !ok { + return nil, [32]byte{}, errors.New("could not cast obj to SSZUint64") + } + obj = spectypes.SSZUint64(data) + case genesisspectypes.DomainSyncCommittee: + data, ok := obj.(genesisspectypes.SSZBytes) + if !ok { + return nil, [32]byte{}, errors.New("could not cast obj to SSZBytes") + } + obj = spectypes.SSZBytes(data) + case genesisspectypes.DomainSyncCommitteeSelectionProof: + case genesisspectypes.DomainContributionAndProof: + case genesisspectypes.DomainApplicationBuilder: + default: + return nil, [32]byte{}, errors.New("domain unknown") + } + signature, root, err := k.KeyManager.SignBeaconObject(obj, domain, pk, domainType) if err != nil { return nil, [32]byte{}, err