Skip to content
Snippets Groups Projects
Commit 565e09f3 authored by Hans Moog's avatar Hans Moog
Browse files

Refactor: refactored some code

parent 2077d6a3
No related branches found
No related tags found
No related merge requests found
......@@ -5,5 +5,6 @@ import (
)
var (
ErrSigningFailed = errors.Wrap(errors.New("failed to sign"), "failed to sign")
ErrSigningFailed = errors.Wrap(errors.New("failed to sign"), "failed to sign")
ErrSignatureCorrupt = errors.Wrap(errors.New("failed to sign"), "failed to sign")
)
......@@ -17,7 +17,7 @@ import (
type Heartbeat struct {
nodeId string
mainStatement *OpinionStatement
neighborStatements map[string]*OpinionStatement
neighborStatements map[string][]*OpinionStatement
signature []byte
nodeIdMutex sync.RWMutex
......@@ -58,14 +58,14 @@ func (heartbeat *Heartbeat) SetMainStatement(mainStatement *OpinionStatement) {
heartbeat.mainStatement = mainStatement
}
func (heartbeat *Heartbeat) GetNeighborStatements() map[string]*OpinionStatement {
func (heartbeat *Heartbeat) GetNeighborStatements() map[string][]*OpinionStatement {
heartbeat.neighborStatementsMutex.RLock()
defer heartbeat.neighborStatementsMutex.RUnlock()
return heartbeat.neighborStatements
}
func (heartbeat *Heartbeat) SetNeighborStatements(neighborStatements map[string]*OpinionStatement) {
func (heartbeat *Heartbeat) SetNeighborStatements(neighborStatements map[string][]*OpinionStatement) {
heartbeat.neighborStatementsMutex.Lock()
defer heartbeat.neighborStatementsMutex.Unlock()
......@@ -79,6 +79,13 @@ func (heartbeat *Heartbeat) GetSignature() []byte {
return heartbeat.signature
}
func (heartbeat *Heartbeat) SetSignature(signature []byte) {
heartbeat.signatureMutex.Lock()
defer heartbeat.signatureMutex.Unlock()
heartbeat.signature = signature
}
func (heartbeat *Heartbeat) Sign(identity *identity.Identity) (err errors.IdentifiableError) {
if marshaledHeartbeat, marshalErr := heartbeat.MarshalBinary(); marshalErr == nil {
if signature, signingErr := identity.Sign(marshaledHeartbeat); signingErr == nil {
......@@ -93,11 +100,25 @@ func (heartbeat *Heartbeat) Sign(identity *identity.Identity) (err errors.Identi
return
}
func (heartbeat *Heartbeat) SetSignature(signature []byte) {
heartbeat.signatureMutex.Lock()
defer heartbeat.signatureMutex.Unlock()
func (heartbeat *Heartbeat) VerifySignature() (result bool, err errors.IdentifiableError) {
signature := heartbeat.GetSignature()
heartbeat.SetSignature(nil)
heartbeat.signature = signature
if marshaledHeartbeat, marshalErr := heartbeat.MarshalBinary(); marshalErr != nil {
heartbeat.SetSignature(signature)
err = marshalErr
} else {
heartbeat.SetSignature(signature)
if identity, identityErr := identity.FromSignedData(marshaledHeartbeat, signature); identityErr != nil {
err = ErrSignatureCorrupt.Derive(identityErr, "failed to retrieve identity from signature of heartbeat")
} else {
result = identity.StringIdentifier == heartbeat.GetNodeId()
}
}
return
}
func (heartbeat *Heartbeat) FromProto(proto proto.Message) {
......@@ -106,12 +127,16 @@ func (heartbeat *Heartbeat) FromProto(proto proto.Message) {
var mainStatement OpinionStatement
mainStatement.FromProto(protoHeartbeat.MainStatement)
neighborStatements := make(map[string]*OpinionStatement, len(protoHeartbeat.NeighborStatements))
neighborStatements := make(map[string][]*OpinionStatement, len(protoHeartbeat.NeighborStatements))
for _, neighborStatement := range protoHeartbeat.NeighborStatements {
var newNeighborStatement OpinionStatement
newNeighborStatement.FromProto(neighborStatement)
neighborStatements[neighborStatement.NodeId] = &newNeighborStatement
if _, exists := neighborStatements[neighborStatement.NodeId]; !exists {
neighborStatements[neighborStatement.NodeId] = make([]*OpinionStatement, 0)
}
neighborStatements[neighborStatement.NodeId] = append(neighborStatements[neighborStatement.NodeId], &newNeighborStatement)
}
heartbeat.nodeId = protoHeartbeat.NodeId
......@@ -123,10 +148,12 @@ func (heartbeat *Heartbeat) FromProto(proto proto.Message) {
func (heartbeat *Heartbeat) ToProto() proto.Message {
neighborStatements := make([]*heartbeatProto.OpinionStatement, len(heartbeat.neighborStatements))
i := 0
for _, neighborStatement := range heartbeat.neighborStatements {
neighborStatements[i] = neighborStatement.ToProto().(*heartbeatProto.OpinionStatement)
for _, statementsOfNeighbor := range heartbeat.neighborStatements {
for _, neighborStatement := range statementsOfNeighbor {
neighborStatements[i] = neighborStatement.ToProto().(*heartbeatProto.OpinionStatement)
i++
i++
}
}
return &heartbeatProto.HeartBeat{
......
......@@ -32,6 +32,12 @@ func NewHeartbeatManager(identity *identity.Identity, options ...HeartbeatManage
}
}
func (heartbeatManager *HeartbeatManager) AddNeighbor(neighborIdentity *identity.Identity) {
if _, exists := heartbeatManager.neighborManagers[neighborIdentity.StringIdentifier]; !exists {
heartbeatManager.neighborManagers[neighborIdentity.StringIdentifier] = NewNeighborManager()
}
}
func (heartbeatManager *HeartbeatManager) InitialDislike(transactionId []byte) {
heartbeatManager.initialOpinions[string(transactionId)] = false
}
......@@ -41,16 +47,20 @@ func (heartbeatManager *HeartbeatManager) InitialLike(transactionId []byte) {
}
func (heartbeatManager *HeartbeatManager) GenerateHeartbeat() (result *heartbeat.Heartbeat, err errors.IdentifiableError) {
if mainStatement, mainStatementErr := heartbeatManager.GenerateMainStatement(); mainStatementErr == nil {
generatedHeartbeat := heartbeat.NewHeartbeat()
generatedHeartbeat.SetNodeId(heartbeatManager.identity.StringIdentifier)
generatedHeartbeat.SetMainStatement(mainStatement)
generatedHeartbeat.SetNeighborStatements(nil)
if signingErr := generatedHeartbeat.Sign(heartbeatManager.identity); signingErr == nil {
result = generatedHeartbeat
if mainStatement, mainStatementErr := heartbeatManager.generateMainStatement(); mainStatementErr == nil {
if neighborStatements, neighborStatementErr := heartbeatManager.generateNeighborStatements(); neighborStatementErr == nil {
generatedHeartbeat := heartbeat.NewHeartbeat()
generatedHeartbeat.SetNodeId(heartbeatManager.identity.StringIdentifier)
generatedHeartbeat.SetMainStatement(mainStatement)
generatedHeartbeat.SetNeighborStatements(neighborStatements)
if signingErr := generatedHeartbeat.Sign(heartbeatManager.identity); signingErr == nil {
result = generatedHeartbeat
} else {
err = signingErr
}
} else {
err = signingErr
err = neighborStatementErr
}
} else {
err = mainStatementErr
......@@ -59,11 +69,35 @@ func (heartbeatManager *HeartbeatManager) GenerateHeartbeat() (result *heartbeat
return
}
func (heartbeatManager *HeartbeatManager) GenerateMainStatement() (result *heartbeat.OpinionStatement, err errors.IdentifiableError) {
func (heartbeatManager *HeartbeatManager) ApplyHeartbeat(heartbeat *heartbeat.Heartbeat) (err errors.IdentifiableError) {
heartbeatManager.neighborManagersMutex.RLock()
defer heartbeatManager.neighborManagersMutex.RUnlock()
if signatureValid, signatureErr := heartbeat.VerifySignature(); signatureErr == nil {
if signatureValid {
issuerId := heartbeat.GetNodeId()
neighborManager, neighborExists := heartbeatManager.neighborManagers[issuerId]
if !neighborExists {
err = ErrUnknownNeighbor.Derive("unknown neighbor: " + issuerId)
} else {
err = neighborManager.ApplyHeartbeat(heartbeat)
}
} else {
err = ErrMalformedHeartbeat.Derive("the heartbeat has an invalid signature")
}
} else {
err = signatureErr
}
return
}
func (heartbeatManager *HeartbeatManager) generateMainStatement() (result *heartbeat.OpinionStatement, err errors.IdentifiableError) {
mainStatement := heartbeat.NewOpinionStatement()
mainStatement.SetNodeId(heartbeatManager.identity.StringIdentifier)
mainStatement.SetTime(uint64(time.Now().Unix()))
mainStatement.SetToggledTransactions(heartbeatManager.GenerateToggledTransactions())
mainStatement.SetToggledTransactions(heartbeatManager.generateToggledTransactions())
if lastAppliedStatement := heartbeatManager.statementChain.lastAppliedStatement; lastAppliedStatement != nil {
mainStatement.SetPreviousStatementHash(lastAppliedStatement.GetHash())
......@@ -72,7 +106,7 @@ func (heartbeatManager *HeartbeatManager) GenerateMainStatement() (result *heart
if signingErr := mainStatement.Sign(heartbeatManager.identity); signingErr == nil {
result = mainStatement
heartbeatManager.ResetInitialOpinions()
heartbeatManager.resetInitialOpinions()
heartbeatManager.statementChain.lastAppliedStatement = mainStatement
} else {
err = signingErr
......@@ -81,7 +115,11 @@ func (heartbeatManager *HeartbeatManager) GenerateMainStatement() (result *heart
return
}
func (heartbeatManager *HeartbeatManager) GenerateToggledTransactions() []*heartbeat.ToggledTransaction {
func (heartbeatManager *HeartbeatManager) generateNeighborStatements() (result map[string][]*heartbeat.OpinionStatement, err errors.IdentifiableError) {
return
}
func (heartbeatManager *HeartbeatManager) generateToggledTransactions() []*heartbeat.ToggledTransaction {
toggledTransactions := make([]*heartbeat.ToggledTransaction, 0)
for transactionId, liked := range heartbeatManager.initialOpinions {
if !liked {
......@@ -97,22 +135,6 @@ func (heartbeatManager *HeartbeatManager) GenerateToggledTransactions() []*heart
return toggledTransactions
}
func (heartbeatManager *HeartbeatManager) ResetInitialOpinions() {
func (heartbeatManager *HeartbeatManager) resetInitialOpinions() {
heartbeatManager.initialOpinions = make(map[string]bool)
}
func (heartbeatManager *HeartbeatManager) ApplyHeartbeat(heartbeat *heartbeat.Heartbeat) (err errors.IdentifiableError) {
heartbeatManager.neighborManagersMutex.RLock()
defer heartbeatManager.neighborManagersMutex.RUnlock()
issuerId := heartbeat.GetNodeId()
neighborManager, neighborExists := heartbeatManager.neighborManagers[issuerId]
if !neighborExists {
err = ErrUnknownNeighbor.Derive("unknown neighbor: " + issuerId)
} else {
err = neighborManager.ApplyHeartbeat(heartbeat)
}
return
}
......@@ -16,30 +16,41 @@ func generateRandomTransactionId() (result []byte) {
}
func TestHeartbeatManager_GenerateHeartbeat(t *testing.T) {
transactionId1 := generateRandomTransactionId()
transactionId2 := generateRandomTransactionId()
ownIdentity := identity.GenerateRandomIdentity()
neighborIdentity := identity.GenerateRandomIdentity()
heartbeatManager := NewHeartbeatManager(identity.GenerateRandomIdentity())
heartbeatManager.InitialDislike(transactionId1)
heartbeatManager.InitialDislike(transactionId2)
// generate first heartbeat ////////////////////////////////////////////////////////////////////////////////////////
heartbeatManager.InitialLike(generateRandomTransactionId())
heartbeatManager1 := NewHeartbeatManager(ownIdentity)
heartbeatManager1.AddNeighbor(neighborIdentity)
heartbeatManager1.InitialDislike(generateRandomTransactionId())
heartbeatManager1.InitialDislike(generateRandomTransactionId())
heartbeatManager1.InitialLike(generateRandomTransactionId())
result, err := heartbeatManager.GenerateHeartbeat()
heartbeat1, err := heartbeatManager1.GenerateHeartbeat()
if err != nil {
t.Error(err)
return
}
fmt.Println(result)
fmt.Println(heartbeat1)
result, err = heartbeatManager.GenerateHeartbeat()
heartbeatManager2 := NewHeartbeatManager(neighborIdentity)
heartbeatManager2.AddNeighbor(ownIdentity)
err = heartbeatManager2.ApplyHeartbeat(heartbeat1)
if err != nil {
t.Error(err)
return
}
fmt.Println(result)
heartbeat2, err := heartbeatManager2.GenerateHeartbeat()
if err != nil {
t.Error(err)
return
}
fmt.Println(heartbeat2)
}
......@@ -63,13 +63,17 @@ func (neighborManager *NeighborManager) ApplyHeartbeat(heartbeat *heartbeat.Hear
}
// check if referenced neighbor statements are missing
for neighborId, neighborStatement := range neighborStatements {
for neighborId, statementsOfNeighbor := range neighborStatements {
neighborChain, exists := neighborManager.neighborChains[neighborId]
if exists {
lastAppliedNeighborStatement := neighborChain.GetLastAppliedStatement()
if lastAppliedNeighborStatement != nil && !bytes.Equal(lastAppliedNeighborStatement.GetHash(), neighborStatement.GetPreviousStatementHash()) {
return ErrMalformedHeartbeat.Derive("missing neighbor statement")
for _, neighborStatement := range statementsOfNeighbor {
lastAppliedNeighborStatement := neighborChain.GetLastAppliedStatement()
if lastAppliedNeighborStatement != nil && !bytes.Equal(lastAppliedNeighborStatement.GetHash(), neighborStatement.GetPreviousStatementHash()) {
return ErrMalformedHeartbeat.Derive("missing neighbor statement")
}
}
} else {
// 1. check if new slot is available (not full || statement of neighbor with last connection)
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment