refactoring

This commit is contained in:
programmer10110 2020-08-25 15:56:27 +03:00
parent 8d63a7f31c
commit 7eb9b15bd9
5 changed files with 96 additions and 105 deletions

View File

@ -169,11 +169,9 @@ func (am *AirgappedMachine) decryptData(data []byte) ([]byte, error) {
return decryptedData, nil
}
func (am *AirgappedMachine) HandleOperation(operation client.Operation) ([]client.Operation, error) {
func (am *AirgappedMachine) HandleOperation(operation client.Operation) (client.Operation, error) {
var (
err error
// output operations (cause of deals)
operations []client.Operation
)
am.Lock()
@ -187,7 +185,7 @@ func (am *AirgappedMachine) HandleOperation(operation client.Operation) ([]clien
case dkg_proposal_fsm.StateDkgCommitsAwaitConfirmations:
err = am.handleStateDkgCommitsAwaitConfirmations(&operation)
case dkg_proposal_fsm.StateDkgDealsAwaitConfirmations:
operations, err = am.handleStateDkgDealsAwaitConfirmations(operation)
err = am.handleStateDkgDealsAwaitConfirmations(&operation)
case dkg_proposal_fsm.StateDkgResponsesAwaitConfirmations:
err = am.handleStateDkgResponsesAwaitConfirmations(&operation)
case dkg_proposal_fsm.StateDkgMasterKeyAwaitConfirmations:
@ -205,15 +203,11 @@ func (am *AirgappedMachine) HandleOperation(operation client.Operation) ([]clien
//}
}
if len(operation.Result) > 0 {
operations = append(operations, operation)
}
return operations, nil
return operation, nil
}
// HandleQR - gets an operation from a QR code, do necessary things for the operation and returns paths to QR-code images
func (am *AirgappedMachine) HandleQR() ([]string, error) {
func (am *AirgappedMachine) HandleQR() (string, error) {
var (
err error
@ -221,36 +215,31 @@ func (am *AirgappedMachine) HandleQR() ([]string, error) {
operation client.Operation
qrData []byte
// output operations (cause of deals)
operations []client.Operation
resultOperation client.Operation
)
if qrData, err = am.qrProcessor.ReadQR(); err != nil {
return nil, fmt.Errorf("failed to read QR: %w", err)
return "", fmt.Errorf("failed to read QR: %w", err)
}
if err = json.Unmarshal(qrData, &operation); err != nil {
return nil, fmt.Errorf("failed to unmarshal operation: %w", err)
return "", fmt.Errorf("failed to unmarshal operation: %w", err)
}
if operations, err = am.HandleOperation(operation); err != nil {
return nil, err
if resultOperation, err = am.HandleOperation(operation); err != nil {
return "", err
}
qrPath := "%s/%s_%s_%s.png"
qrPaths := make([]string, 0, len(operations))
for _, o := range operations {
operationBz, err := json.Marshal(o)
if err != nil {
return nil, fmt.Errorf("failed to marshal operation: %w", err)
}
if err = am.qrProcessor.WriteQR(fmt.Sprintf(qrPath, resultQRFolder, o.Type, o.ID, o.To), operationBz); err != nil {
return nil, fmt.Errorf("failed to write QR")
}
qrPaths = append(qrPaths, qrPath)
qrPath := fmt.Sprintf("%s/%s_%s_%s.png", resultQRFolder, resultOperation.Type, resultOperation.ID, resultOperation.To)
operationBz, err := json.Marshal(resultOperation)
if err != nil {
return "", fmt.Errorf("failed to marshal operation: %w", err)
}
return qrPaths, nil
if err = am.qrProcessor.WriteQR(qrPath, operationBz); err != nil {
return "", fmt.Errorf("failed to write QR")
}
return qrPath, nil
}
func (am *AirgappedMachine) writeErrorRequestToOperation(o *client.Operation, handlerError error) error {
@ -276,7 +265,7 @@ func (am *AirgappedMachine) writeErrorRequestToOperation(o *client.Operation, ha
if err != nil {
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = errorEvent
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
return nil
}

View File

@ -5,9 +5,11 @@ import (
"encoding/json"
"fmt"
client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/fsm"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses"
"github.com/depools/dc4bc/storage"
"github.com/google/uuid"
"sync"
"testing"
@ -29,34 +31,34 @@ type Node struct {
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
}
func (n *Node) storeOperation(t *testing.T, o client.Operation) {
switch o.Event {
func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
switch fsm.Event(msg.Event) {
case dkg_proposal_fsm.EventDKGCommitConfirmationReceived:
var req requests.DKGProposalCommitConfirmationRequest
if err := json.Unmarshal(o.Result, &req); err != nil {
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.commits = append(n.commits, req)
case dkg_proposal_fsm.EventDKGDealConfirmationReceived:
var req requests.DKGProposalDealConfirmationRequest
if err := json.Unmarshal(o.Result, &req); err != nil {
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.deals = append(n.deals, req)
case dkg_proposal_fsm.EventDKGResponseConfirmationReceived:
var req requests.DKGProposalResponseConfirmationRequest
if err := json.Unmarshal(o.Result, &req); err != nil {
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.responses = append(n.responses, req)
case dkg_proposal_fsm.EventDKGMasterKeyConfirmationReceived:
var req requests.DKGProposalMasterKeyConfirmationRequest
if err := json.Unmarshal(o.Result, &req); err != nil {
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.masterKeys = append(n.masterKeys, req)
default:
t.Fatalf("invalid event: %s", o.Event)
t.Fatalf("invalid event: %s", msg.Event)
}
}
@ -64,10 +66,10 @@ type Transport struct {
nodes []*Node
}
func (tr *Transport) BroadcastOperation(t *testing.T, operation client.Operation) {
func (tr *Transport) BroadcastMessage(t *testing.T, msg storage.Message) {
for _, node := range tr.nodes {
if operation.To == "" || operation.To == node.Participant {
node.storeOperation(t, operation)
if msg.RecipientAddr == "" || msg.RecipientAddr == node.Participant {
node.storeOperation(t, msg)
}
}
}
@ -81,7 +83,6 @@ func createOperation(t *testing.T, opType string, to string, req interface{}) cl
ID: uuid.New().String(),
Type: client.OperationType(opType),
Payload: reqBz,
Result: nil,
CreatedAt: time.Now(),
DKGIdentifier: DKGIdentifier,
To: to,
@ -90,7 +91,7 @@ func createOperation(t *testing.T, opType string, to string, req interface{}) cl
}
func TestAirgappedAllSteps(t *testing.T) {
nodesCount := 13
nodesCount := 25
participants := make([]string, nodesCount)
for i := 0; i < nodesCount; i++ {
participants[i] = fmt.Sprintf("Participant#%d", i)
@ -147,12 +148,12 @@ func TestAirgappedAllSteps(t *testing.T) {
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
defer wg.Done()
operations, err := n.Machine.HandleOperation(op)
operation, err := n.Machine.HandleOperation(op)
if err != nil {
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
}
for _, op := range operations {
tr.BroadcastOperation(t, op)
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})
@ -171,12 +172,12 @@ func TestAirgappedAllSteps(t *testing.T) {
}
op := createOperation(t, string(dkg_proposal_fsm.StateDkgDealsAwaitConfirmations), "", payload)
operations, err := n.Machine.HandleOperation(op)
operation, err := n.Machine.HandleOperation(op)
if err != nil {
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
}
for _, op := range operations {
tr.BroadcastOperation(t, op)
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})
@ -195,12 +196,12 @@ func TestAirgappedAllSteps(t *testing.T) {
}
op := createOperation(t, string(dkg_proposal_fsm.StateDkgResponsesAwaitConfirmations), "", payload)
operations, err := n.Machine.HandleOperation(op)
operation, err := n.Machine.HandleOperation(op)
if err != nil {
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
}
for _, op := range operations {
tr.BroadcastOperation(t, op)
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})
@ -219,12 +220,12 @@ func TestAirgappedAllSteps(t *testing.T) {
}
op := createOperation(t, string(dkg_proposal_fsm.StateDkgMasterKeyAwaitConfirmations), "", payload)
operations, err := n.Machine.HandleOperation(op)
operation, err := n.Machine.HandleOperation(op)
if err != nil {
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
}
for _, op := range operations {
tr.BroadcastOperation(t, op)
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})

View File

@ -9,11 +9,21 @@ import (
"github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses"
"github.com/depools/dc4bc/storage"
"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/pairing/bn256"
dkgPedersen "go.dedis.ch/kyber/v3/share/dkg/pedersen"
)
func createMessage(o client.Operation, data []byte) storage.Message {
return storage.Message{
Event: string(o.Event),
Data: data,
DkgRoundID: o.DKGIdentifier,
RecipientAddr: o.To,
}
}
func (am *AirgappedMachine) handleStateAwaitParticipantsConfirmations(o *client.Operation) error {
var (
payload responses.SignatureProposalParticipantInvitationsResponse
@ -53,9 +63,9 @@ func (am *AirgappedMachine) handleStateAwaitParticipantsConfirmations(o *client.
if err != nil {
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = signature_proposal_fsm.EventConfirmSignatureProposal
o.Event = signature_proposal_fsm.EventConfirmSignatureProposal
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
return nil
}
@ -114,13 +124,13 @@ func (am *AirgappedMachine) handleStateDkgCommitsAwaitConfirmations(o *client.Op
if err != nil {
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = dkg_proposal_fsm.EventDKGCommitConfirmationReceived
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
return nil
}
// We have many deals which should be sent privately to a required participant, so func returns a slice of operations
func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o client.Operation) ([]client.Operation, error) {
func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o *client.Operation) error {
var (
payload responses.DKGProposalCommitParticipantResponse
err error
@ -128,23 +138,23 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o client.Opera
dkgInstance, ok := am.dkgInstances[o.DKGIdentifier]
if !ok {
return nil, fmt.Errorf("dkg instance with identifier %s does not exist", o.DKGIdentifier)
return fmt.Errorf("dkg instance with identifier %s does not exist", o.DKGIdentifier)
}
if err = json.Unmarshal(o.Payload, &payload); err != nil {
return nil, fmt.Errorf("failed to unmarshal payload: %w", err)
return fmt.Errorf("failed to unmarshal payload: %w", err)
}
for _, entry := range payload {
var commitsBz [][]byte
if err = json.Unmarshal(entry.DkgCommit, &commitsBz); err != nil {
return nil, fmt.Errorf("failed to unmarshal commits: %w", err)
return fmt.Errorf("failed to unmarshal commits: %w", err)
}
dkgCommits := make([]kyber.Point, 0, len(commitsBz))
for _, commitBz := range commitsBz {
commit := am.suite.Point()
if err = commit.UnmarshalBinary(commitBz); err != nil {
return nil, fmt.Errorf("failed to unmarshal commit: %w", err)
return fmt.Errorf("failed to unmarshal commit: %w", err)
}
dkgCommits = append(dkgCommits, commit)
}
@ -153,23 +163,21 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o client.Opera
deals, err := dkgInstance.GetDeals()
if err != nil {
return nil, fmt.Errorf("failed to get deals: %w", err)
return fmt.Errorf("failed to get deals: %w", err)
}
operations := make([]client.Operation, 0, len(deals))
am.dkgInstances[o.DKGIdentifier] = dkgInstance
// deals variable is a map, so every key is an index of participant we should send a deal
for index, deal := range deals {
dealBz, err := json.Marshal(deal)
if err != nil {
return nil, fmt.Errorf("failed to marshal deal: %w", err)
return fmt.Errorf("failed to marshal deal: %w", err)
}
toParticipant := dkgInstance.GetParticipantByIndex(index)
encryptedDeal, err := am.encryptData(o.DKGIdentifier, toParticipant, dealBz)
if err != nil {
return nil, fmt.Errorf("failed to encrypt deal: %w", err)
return fmt.Errorf("failed to encrypt deal: %w", err)
}
req := requests.DKGProposalDealConfirmationRequest{
ParticipantId: dkgInstance.ParticipantID,
@ -179,13 +187,12 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o client.Opera
o.To = toParticipant
reqBz, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("failed to generate fsm request: %w", err)
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = dkg_proposal_fsm.EventDKGDealConfirmationReceived
operations = append(operations, o)
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
}
return operations, nil
return nil
}
func (am *AirgappedMachine) handleStateDkgResponsesAwaitConfirmations(o *client.Operation) error {
@ -238,8 +245,8 @@ func (am *AirgappedMachine) handleStateDkgResponsesAwaitConfirmations(o *client.
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = dkg_proposal_fsm.EventDKGResponseConfirmationReceived
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
return nil
}
@ -301,8 +308,8 @@ func (am *AirgappedMachine) handleStateDkgMasterKeyAwaitConfirmations(o *client.
return fmt.Errorf("failed to generate fsm request: %w", err)
}
o.Result = reqBz
o.Event = dkg_proposal_fsm.EventDKGMasterKeyConfirmationReceived
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
fmt.Println(dkgInstance.ParticipantID, pubKey.String())

View File

@ -118,19 +118,17 @@ func (c *Client) Poll() error {
c.logger.Log("Got %d Operations from pool", len(operations))
for _, operation := range operations {
c.logger.Log("Handling operation %s in airgapped", operation.Type)
processedOperations, err := c.Airgapped.HandleOperation(*operation)
processedOperation, err := c.Airgapped.HandleOperation(*operation)
if err != nil {
c.logger.Log("Failed to handle operation: %v", err)
}
c.logger.Log("Got %d Processed Operations from Airgapped", len(operations))
for _, processedOperation := range processedOperations {
c.logger.Log("Operation %s handled in airgapped, result event is %s", operation.Event, processedOperation.Event)
if err = c.handleProcessedOperation(processedOperation); err != nil {
c.logger.Log("Failed to handle processed operation: %v", err)
} else {
c.logger.Log("Successfully handled processed operation %s", processedOperation.Event)
}
c.logger.Log("Operation %s handled in airgapped, result event is %s", operation.Event, processedOperation.Event)
if err = c.handleProcessedOperation(processedOperation); err != nil {
c.logger.Log("Failed to handle processed operation: %v", err)
} else {
c.logger.Log("Successfully handled processed operation %s", processedOperation.Event)
}
}
case <-c.ctx.Done():
@ -281,31 +279,27 @@ func (c *Client) ReadProcessedOperation() error {
}
func (c *Client) handleProcessedOperation(operation types.Operation) error {
//storedOperation, err := c.state.GetOperationByID(operation.ID)
//if err != nil {
// return fmt.Errorf("failed to find matching operation: %w", err)
//}
//
//if err := storedOperation.Check(&operation); err != nil {
// return fmt.Errorf("processed operation does not match stored operation: %w", err)
//}
message := storage.Message{
Event: string(operation.Event),
Data: operation.Result,
DkgRoundID: operation.DKGIdentifier,
SenderAddr: c.GetAddr(),
RecipientAddr: operation.To,
}
sig, err := c.signMessage(message.Bytes())
storedOperation, err := c.state.GetOperationByID(operation.ID)
if err != nil {
return fmt.Errorf("failed to sign a message: %w", err)
return fmt.Errorf("failed to find matching operation: %w", err)
}
message.Signature = sig
if _, err := c.storage.Send(message); err != nil {
return fmt.Errorf("failed to post message: %w", err)
if err := storedOperation.Check(&operation); err != nil {
return fmt.Errorf("processed operation does not match stored operation: %w", err)
}
for _, message := range operation.ResultMsgs {
message.SenderAddr = c.GetAddr()
sig, err := c.signMessage(message.Bytes())
if err != nil {
return fmt.Errorf("failed to sign a message: %w", err)
}
message.Signature = sig
if _, err := c.storage.Send(message); err != nil {
return fmt.Errorf("failed to post message: %w", err)
}
}
if err := c.state.DeleteOperation(operation.ID); err != nil {

View File

@ -23,7 +23,7 @@ type Operation struct {
ID string // UUID4
Type OperationType
Payload []byte
Result []byte
ResultMsgs []storage.Message
CreatedAt time.Time
DKGIdentifier string
To string