airgapped machine in tests, move client types.go to different package

This commit is contained in:
programmer10110 2020-08-20 18:08:11 +03:00
parent bfcd7d6eb4
commit 950e7369b4
12 changed files with 80 additions and 40 deletions

View File

@ -3,7 +3,7 @@ package airgapped
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/client" client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/dkg" "github.com/depools/dc4bc/dkg"
"github.com/depools/dc4bc/fsm/fsm" "github.com/depools/dc4bc/fsm/fsm"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm" "github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"

View File

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/client" client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm" "github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests" "github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses" "github.com/depools/dc4bc/fsm/types/responses"
@ -138,7 +138,7 @@ func TestAirgappedAllSteps(t *testing.T) {
} }
entry := &responses.SignatureProposalParticipantStatusEntry{ entry := &responses.SignatureProposalParticipantStatusEntry{
ParticipantId: n.ParticipantID, ParticipantId: n.ParticipantID,
Addr: n.Participant, Addr: n.Participant,
DkgPubKey: pubKey, DkgPubKey: pubKey,
} }
getCommitsRequest = append(getCommitsRequest, entry) getCommitsRequest = append(getCommitsRequest, entry)

View File

@ -3,7 +3,7 @@ package airgapped
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/client" client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm" "github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests" "github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses" "github.com/depools/dc4bc/fsm/types/responses"

View File

@ -3,7 +3,7 @@ package airgapped
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/client" client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/dkg" "github.com/depools/dc4bc/dkg"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm" "github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests" "github.com/depools/dc4bc/fsm/types/requests"

View File

@ -6,6 +6,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/depools/dc4bc/airgapped"
"github.com/depools/dc4bc/client/types"
"log" "log"
"path/filepath" "path/filepath"
"sync" "sync"
@ -37,6 +39,7 @@ type Client struct {
storage storage.Storage storage storage.Storage
keyStore KeyStore keyStore KeyStore
qrProcessor qr.Processor qrProcessor qr.Processor
airgapped *airgapped.AirgappedMachine
} }
func NewClient( func NewClient(
@ -46,6 +49,7 @@ func NewClient(
storage storage.Storage, storage storage.Storage,
keyStore KeyStore, keyStore KeyStore,
qrProcessor qr.Processor, qrProcessor qr.Processor,
airgappedMachine *airgapped.AirgappedMachine,
) (*Client, error) { ) (*Client, error) {
keyPair, err := keyStore.LoadKeys(userName, "") keyPair, err := keyStore.LoadKeys(userName, "")
if err != nil { if err != nil {
@ -61,6 +65,7 @@ func NewClient(
storage: storage, storage: storage,
keyStore: keyStore, keyStore: keyStore,
qrProcessor: qrProcessor, qrProcessor: qrProcessor,
airgapped: airgappedMachine,
}, nil }, nil
} }
@ -92,6 +97,22 @@ func (c *Client) Poll() error {
log.Println("Failed to process message:", err) log.Println("Failed to process message:", err)
} }
} }
operations, err := c.GetOperations()
if err != nil {
log.Println("Failed to get operations: %v", err)
}
for _, operation := range operations {
processedOperations, err := c.airgapped.HandleOperation(*operation)
if err != nil {
return fmt.Errorf("failed to process operation in airgapped: %w", err)
}
for _, po := range processedOperations {
if err = c.handleProcessedOperation(po); err != nil {
return fmt.Errorf("failed to handle processed operation")
}
}
}
case <-c.ctx.Done(): case <-c.ctx.Done():
log.Println("Context closed, stop polling...") log.Println("Context closed, stop polling...")
return nil return nil
@ -119,7 +140,7 @@ func (c *Client) ProcessMessage(message storage.Message) error {
} }
} }
fsmReq, err := FSMRequestFromMessage(message) fsmReq, err := types.FSMRequestFromMessage(message)
if err != nil { if err != nil {
return fmt.Errorf("failed to get FSMRequestFromMessage: %v", err) return fmt.Errorf("failed to get FSMRequestFromMessage: %v", err)
} }
@ -129,7 +150,7 @@ func (c *Client) ProcessMessage(message storage.Message) error {
return fmt.Errorf("failed to Do operation in FSM: %w", err) return fmt.Errorf("failed to Do operation in FSM: %w", err)
} }
var operation *Operation var operation *types.Operation
switch resp.State { switch resp.State {
// if the new state is waiting for RPC to airgapped machine // if the new state is waiting for RPC to airgapped machine
case case
@ -142,8 +163,8 @@ func (c *Client) ProcessMessage(message storage.Message) error {
return fmt.Errorf("failed to marshal FSM response: %w", err) return fmt.Errorf("failed to marshal FSM response: %w", err)
} }
operation = &Operation{ operation = &types.Operation{
Type: OperationType(resp.State), Type: types.OperationType(resp.State),
Payload: bz, Payload: bz,
} }
default: default:
@ -167,7 +188,7 @@ func (c *Client) ProcessMessage(message storage.Message) error {
return nil return nil
} }
func (c *Client) GetOperations() (map[string]*Operation, error) { func (c *Client) GetOperations() (map[string]*types.Operation, error) {
return c.state.GetOperations() return c.state.GetOperations()
} }
@ -210,7 +231,7 @@ func (c *Client) ReadProcessedOperation() error {
return fmt.Errorf("failed to ReadQR: %s", err) return fmt.Errorf("failed to ReadQR: %s", err)
} }
var operation Operation var operation types.Operation
if err = json.Unmarshal(bz, &operation); err != nil { if err = json.Unmarshal(bz, &operation); err != nil {
return fmt.Errorf("failed to unmarshal processed operation") return fmt.Errorf("failed to unmarshal processed operation")
} }
@ -218,7 +239,7 @@ func (c *Client) ReadProcessedOperation() error {
return c.handleProcessedOperation(operation) return c.handleProcessedOperation(operation)
} }
func (c *Client) handleProcessedOperation(operation Operation) error { func (c *Client) handleProcessedOperation(operation types.Operation) error {
storedOperation, err := c.state.GetOperationByID(operation.ID) storedOperation, err := c.state.GetOperationByID(operation.ID)
if err != nil { if err != nil {
return fmt.Errorf("failed to find matching operation: %w", err) return fmt.Errorf("failed to find matching operation: %w", err)
@ -295,4 +316,4 @@ func (c *Client) verifyMessage(fsmInstance *state_machines.FSMInstance, message
} }
return nil return nil
} }

View File

@ -5,6 +5,7 @@ import (
"crypto/ed25519" "crypto/ed25519"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/depools/dc4bc/client/types"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -48,6 +49,7 @@ func TestClient_ProcessMessage(t *testing.T) {
stg, stg,
keyStore, keyStore,
qrProcessor, qrProcessor,
nil,
) )
req.NoError(err) req.NoError(err)
@ -125,22 +127,23 @@ func TestClient_GetOperationsList(t *testing.T) {
stg, stg,
keyStore, keyStore,
qrProcessor, qrProcessor,
nil,
) )
req.NoError(err) req.NoError(err)
state.EXPECT().GetOperations().Times(1).Return(map[string]*client.Operation{}, nil) state.EXPECT().GetOperations().Times(1).Return(map[string]*types.Operation{}, nil)
operations, err := clt.GetOperations() operations, err := clt.GetOperations()
req.NoError(err) req.NoError(err)
req.Len(operations, 0) req.Len(operations, 0)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
state.EXPECT().GetOperations().Times(1).Return( state.EXPECT().GetOperations().Times(1).Return(
map[string]*client.Operation{operation.ID: operation}, nil) map[string]*types.Operation{operation.ID: operation}, nil)
operations, err = clt.GetOperations() operations, err = clt.GetOperations()
req.NoError(err) req.NoError(err)
req.Len(operations, 1) req.Len(operations, 1)
@ -167,12 +170,13 @@ func TestClient_GetOperationQRPath(t *testing.T) {
stg, stg,
keyStore, keyStore,
qrProcessor, qrProcessor,
nil,
) )
req.NoError(err) req.NoError(err)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
@ -213,19 +217,20 @@ func TestClient_ReadProcessedOperation(t *testing.T) {
stg, stg,
keyStore, keyStore,
qrProcessor, qrProcessor,
nil,
) )
req.NoError(err) req.NoError(err)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
Result: []byte("operation_result"), Result: []byte("operation_result"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
processedOperation := &client.Operation{ processedOperation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
Result: []byte("operation_result"), Result: []byte("operation_result"),
CreatedAt: time.Now(), CreatedAt: time.Now(),

View File

@ -3,6 +3,7 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/client/types"
"image" "image"
"io/ioutil" "io/ioutil"
"log" "log"
@ -168,7 +169,7 @@ func (c *Client) readProcessedOperationFromBodyHandler(w http.ResponseWriter, r
return return
} }
var operation Operation var operation types.Operation
if err = json.Unmarshal(qrData, &operation); err != nil { if err = json.Unmarshal(qrData, &operation); err != nil {
errorResponse(w, http.StatusInternalServerError, errorResponse(w, http.StatusInternalServerError,
fmt.Sprintf("failed to unmarshal processed operation: %v", err)) fmt.Sprintf("failed to unmarshal processed operation: %v", err))

View File

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/depools/dc4bc/client/types"
"sync" "sync"
"github.com/depools/dc4bc/fsm/state_machines" "github.com/depools/dc4bc/fsm/state_machines"
@ -25,10 +26,10 @@ type State interface {
SaveFSM(dkgRoundID string, dump []byte) error SaveFSM(dkgRoundID string, dump []byte) error
LoadFSM(dkgRoundID string) (*state_machines.FSMInstance, bool, error) LoadFSM(dkgRoundID string) (*state_machines.FSMInstance, bool, error)
PutOperation(operation *Operation) error PutOperation(operation *types.Operation) error
DeleteOperation(operationID string) error DeleteOperation(operationID string) error
GetOperations() (map[string]*Operation, error) GetOperations() (map[string]*types.Operation, error)
GetOperationByID(operationID string) (*Operation, error) GetOperationByID(operationID string) (*types.Operation, error)
} }
type LevelDBState struct { type LevelDBState struct {
@ -48,7 +49,7 @@ func NewLevelDBState(stateDbPath string) (State, error) {
// Init state key for operations JSON. // Init state key for operations JSON.
if _, err := state.stateDb.Get([]byte(operationsKey), nil); err != nil { if _, err := state.stateDb.Get([]byte(operationsKey), nil); err != nil {
if err := state.initJsonKey(operationsKey, map[string]*Operation{}); err != nil { if err := state.initJsonKey(operationsKey, map[string]*types.Operation{}); err != nil {
return nil, fmt.Errorf("failed to init %s storage: %w", operationsKey, err) return nil, fmt.Errorf("failed to init %s storage: %w", operationsKey, err)
} }
} }
@ -151,7 +152,7 @@ func (s *LevelDBState) LoadFSM(dkgRoundID string) (*state_machines.FSMInstance,
return fsmInstance, ok, nil return fsmInstance, ok, nil
} }
func (s *LevelDBState) PutOperation(operation *Operation) error { func (s *LevelDBState) PutOperation(operation *types.Operation) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
@ -200,14 +201,14 @@ func (s *LevelDBState) DeleteOperation(operationID string) error {
return nil return nil
} }
func (s *LevelDBState) GetOperations() (map[string]*Operation, error) { func (s *LevelDBState) GetOperations() (map[string]*types.Operation, error) {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
return s.getOperations() return s.getOperations()
} }
func (s *LevelDBState) GetOperationByID(operationID string) (*Operation, error) { func (s *LevelDBState) GetOperationByID(operationID string) (*types.Operation, error) {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
@ -224,13 +225,13 @@ func (s *LevelDBState) GetOperationByID(operationID string) (*Operation, error)
return operation, nil return operation, nil
} }
func (s *LevelDBState) getOperations() (map[string]*Operation, error) { func (s *LevelDBState) getOperations() (map[string]*types.Operation, error) {
bz, err := s.stateDb.Get([]byte(operationsKey), nil) bz, err := s.stateDb.Get([]byte(operationsKey), nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get Operations (key: %s): %w", operationsKey, err) return nil, fmt.Errorf("failed to get Operations (key: %s): %w", operationsKey, err)
} }
var operations map[string]*Operation var operations map[string]*types.Operation
if err := json.Unmarshal(bz, &operations); err != nil { if err := json.Unmarshal(bz, &operations); err != nil {
return nil, fmt.Errorf("failed to unmarshal Operations: %w", err) return nil, fmt.Errorf("failed to unmarshal Operations: %w", err)
} }

View File

@ -1,6 +1,7 @@
package client_test package client_test
import ( import (
"github.com/depools/dc4bc/client/types"
"os" "os"
"testing" "testing"
"time" "time"
@ -38,9 +39,9 @@ func TestLevelDBState_PutOperation(t *testing.T) {
stg, err := client.NewLevelDBState(dbPath) stg, err := client.NewLevelDBState(dbPath)
req.NoError(err) req.NoError(err)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
Result: []byte("operation_result"), Result: []byte("operation_result"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
@ -69,9 +70,9 @@ func TestLevelDBState_GetOperations(t *testing.T) {
stg, err := client.NewLevelDBState(dbPath) stg, err := client.NewLevelDBState(dbPath)
req.NoError(err) req.NoError(err)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_1", ID: "operation_1",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
Result: []byte("operation_result"), Result: []byte("operation_result"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
@ -98,9 +99,9 @@ func TestLevelDBState_DeleteOperation(t *testing.T) {
stg, err := client.NewLevelDBState(dbPath) stg, err := client.NewLevelDBState(dbPath)
req.NoError(err) req.NoError(err)
operation := &client.Operation{ operation := &types.Operation{
ID: "operation_id", ID: "operation_id",
Type: client.DKGCommits, Type: types.DKGCommits,
Payload: []byte("operation_payload"), Payload: []byte("operation_payload"),
Result: []byte("operation_result"), Result: []byte("operation_result"),
CreatedAt: time.Now(), CreatedAt: time.Now(),

View File

@ -1,4 +1,4 @@
package client package types
import ( import (
"bytes" "bytes"

View File

@ -6,6 +6,7 @@ import (
"crypto/md5" "crypto/md5"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/airgapped"
_ "image/jpeg" _ "image/jpeg"
"log" "log"
"sync" "sync"
@ -65,6 +66,11 @@ func main() {
log.Fatalf("Failed to PutKeys: %v\n", err) log.Fatalf("Failed to PutKeys: %v\n", err)
} }
airgappedMachine, err := airgapped.NewAirgappedMachine(fmt.Sprintf("/tmp/dc4bc_node_%d_airgapped_db", nodeID))
if err != nil {
log.Fatalf("Failed to create airgapped machine: %v", err)
}
clt, err := client.NewClient( clt, err := client.NewClient(
ctx, ctx,
userName, userName,
@ -72,6 +78,7 @@ func main() {
stg, stg,
keyStore, keyStore,
qr.NewCameraProcessor(), qr.NewCameraProcessor(),
airgappedMachine,
) )
if err != nil { if err != nil {
log.Fatalf("node %d failed to init client: %v\n", nodeID, err) log.Fatalf("node %d failed to init client: %v\n", nodeID, err)

View File

@ -33,6 +33,10 @@ func (m *MockKeyStore) EXPECT() *MockKeyStoreMockRecorder {
return m.recorder return m.recorder
} }
func (mr *MockKeyStore) PutKeys(userName string, keyPair *client.KeyPair) error {
return nil
}
// LoadKeys mocks base method // LoadKeys mocks base method
func (m *MockKeyStore) LoadKeys(userName, password string) (*client.KeyPair, error) { func (m *MockKeyStore) LoadKeys(userName, password string) (*client.KeyPair, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()