mirror of https://github.com/certusone/dc4bc.git
Merge pull request #8 from p2p-org/feat/client-skeleton
feat: client skeleton
This commit is contained in:
commit
6cb0f59656
|
@ -0,0 +1,9 @@
|
|||
test:
|
||||
@echo "Testing Go packages..."
|
||||
@go test ./... -cover
|
||||
|
||||
mocks:
|
||||
@echo "Regenerate mocks..."
|
||||
@go generate ./...
|
||||
|
||||
.PHONY: mocks
|
|
@ -0,0 +1,153 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/p2p-org/dc4bc/qr"
|
||||
"github.com/p2p-org/dc4bc/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
pollingPeriod = time.Second
|
||||
QrCodesDir = "/tmp"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
ctx context.Context
|
||||
fsm interface{}
|
||||
state State
|
||||
storage storage.Storage
|
||||
qrProcessor qr.Processor
|
||||
}
|
||||
|
||||
func NewClient(
|
||||
ctx context.Context,
|
||||
fsm interface{},
|
||||
state State,
|
||||
storage storage.Storage,
|
||||
qrProcessor qr.Processor,
|
||||
) (*Client, error) {
|
||||
return &Client{
|
||||
ctx: ctx,
|
||||
fsm: fsm,
|
||||
state: state,
|
||||
storage: storage,
|
||||
qrProcessor: qrProcessor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) SendMessage(message storage.Message) error {
|
||||
if _, err := c.storage.Send(message); err != nil {
|
||||
return fmt.Errorf("failed to post message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Poll() {
|
||||
tk := time.NewTicker(pollingPeriod)
|
||||
for {
|
||||
select {
|
||||
case <-tk.C:
|
||||
offset, err := c.state.LoadOffset()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
messages, err := c.storage.GetMessages(offset)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, message := range messages {
|
||||
log.Println("Message:", message)
|
||||
|
||||
// Feed the message to the FSM, get a possibly empty operation.
|
||||
var operation *Operation
|
||||
|
||||
// I.e., if FSM returned an Operation for us.
|
||||
if operation != nil {
|
||||
if err := c.state.PutOperation(operation); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.state.SaveOffset(message.Offset); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := c.state.SaveFSM(c.fsm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
case <-c.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetOperations() (map[string]*Operation, error) {
|
||||
return c.state.GetOperations()
|
||||
}
|
||||
|
||||
// GetOperationQRPath returns a path to the image with the QR generated
|
||||
// for the specified operation. It is supposed that the user will open
|
||||
// this file herself.
|
||||
func (c *Client) GetOperationQRPath(operationID string) (string, error) {
|
||||
operation, err := c.state.GetOperationByID(operationID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get operation: %w", err)
|
||||
}
|
||||
|
||||
operationJSON, err := json.Marshal(operation)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to marshal operation: %w", err)
|
||||
}
|
||||
|
||||
operationQRPath := filepath.Join(QrCodesDir, operationID)
|
||||
if err := c.qrProcessor.WriteQR(operationQRPath, operationJSON); err != nil {
|
||||
return "", fmt.Errorf("failed to WriteQR: %w", err)
|
||||
}
|
||||
|
||||
return operationQRPath, nil
|
||||
}
|
||||
|
||||
// ReadProcessedOperation reads the processed operation from camera, checks that
|
||||
// the processed operation has its unprocessed counterpart in our state,
|
||||
// posts a Message to the storage and deletes the operation from our state.
|
||||
func (c *Client) ReadProcessedOperation() error {
|
||||
bz, err := c.qrProcessor.ReadQR()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to ReadQR: %s", err)
|
||||
}
|
||||
|
||||
var operation Operation
|
||||
if err = json.Unmarshal(bz, &operation); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal processed operation")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
var message storage.Message
|
||||
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 {
|
||||
return fmt.Errorf("failed to DeleteOperation: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package client_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/p2p-org/dc4bc/mocks/qrMocks"
|
||||
|
||||
"github.com/p2p-org/dc4bc/client"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/p2p-org/dc4bc/mocks/clientMocks"
|
||||
"github.com/p2p-org/dc4bc/mocks/storageMocks"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestClient_GetOperationsList(t *testing.T) {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
req = require.New(t)
|
||||
ctrl = gomock.NewController(t)
|
||||
)
|
||||
defer ctrl.Finish()
|
||||
|
||||
state := clientMocks.NewMockState(ctrl)
|
||||
storage := storageMocks.NewMockStorage(ctrl)
|
||||
qrProcessor := qrMocks.NewMockProcessor(ctrl)
|
||||
|
||||
clt, err := client.NewClient(ctx, nil, state, storage, qrProcessor)
|
||||
req.NoError(err)
|
||||
|
||||
state.EXPECT().GetOperations().Times(1).Return(map[string]*client.Operation{}, nil)
|
||||
operations, err := clt.GetOperations()
|
||||
req.NoError(err)
|
||||
req.Len(operations, 0)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
state.EXPECT().GetOperations().Times(1).Return(
|
||||
map[string]*client.Operation{operation.ID: operation}, nil)
|
||||
operations, err = clt.GetOperations()
|
||||
req.NoError(err)
|
||||
req.Len(operations, 1)
|
||||
req.Equal(operation, operations[operation.ID])
|
||||
}
|
||||
|
||||
func TestClient_GetOperationQRPath(t *testing.T) {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
req = require.New(t)
|
||||
ctrl = gomock.NewController(t)
|
||||
)
|
||||
defer ctrl.Finish()
|
||||
|
||||
state := clientMocks.NewMockState(ctrl)
|
||||
storage := storageMocks.NewMockStorage(ctrl)
|
||||
qrProcessor := qrMocks.NewMockProcessor(ctrl)
|
||||
|
||||
clt, err := client.NewClient(ctx, nil, state, storage, qrProcessor)
|
||||
req.NoError(err)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
var expectedQrPath = filepath.Join(client.QrCodesDir, operation.ID)
|
||||
defer os.Remove(expectedQrPath)
|
||||
|
||||
state.EXPECT().GetOperationByID(operation.ID).Times(1).Return(
|
||||
nil, errors.New(""))
|
||||
_, err = clt.GetOperationQRPath(operation.ID)
|
||||
req.Error(err)
|
||||
|
||||
state.EXPECT().GetOperationByID(operation.ID).Times(1).Return(
|
||||
operation, nil)
|
||||
qrProcessor.EXPECT().WriteQR(expectedQrPath, gomock.Any()).Times(1).Return(nil)
|
||||
qrPath, err := clt.GetOperationQRPath(operation.ID)
|
||||
req.NoError(err)
|
||||
req.Equal(expectedQrPath, qrPath)
|
||||
}
|
||||
|
||||
func TestClient_ReadProcessedOperation(t *testing.T) {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
req = require.New(t)
|
||||
ctrl = gomock.NewController(t)
|
||||
)
|
||||
defer ctrl.Finish()
|
||||
|
||||
state := clientMocks.NewMockState(ctrl)
|
||||
storage := storageMocks.NewMockStorage(ctrl)
|
||||
qrProcessor := qrMocks.NewMockProcessor(ctrl)
|
||||
|
||||
clt, err := client.NewClient(ctx, nil, state, storage, qrProcessor)
|
||||
req.NoError(err)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
Result: []byte("operation_result"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
processedOperation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
Result: []byte("operation_result"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
processedOperationBz, err := json.Marshal(processedOperation)
|
||||
req.NoError(err)
|
||||
|
||||
qrProcessor.EXPECT().ReadQR().Return(processedOperationBz, nil).Times(1)
|
||||
state.EXPECT().GetOperationByID(processedOperation.ID).Times(1).Return(operation, nil)
|
||||
state.EXPECT().DeleteOperation(processedOperation.ID).Times(1)
|
||||
storage.EXPECT().Send(gomock.Any()).Times(1)
|
||||
err = clt.ReadProcessedOperation()
|
||||
req.NoError(err)
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
const (
|
||||
offsetKey = "offset"
|
||||
operationsKey = "operations"
|
||||
)
|
||||
|
||||
type State interface {
|
||||
SaveOffset(uint64) error
|
||||
LoadOffset() (uint64, error)
|
||||
|
||||
SaveFSM(interface{}) error
|
||||
LoadFSM() (interface{}, error)
|
||||
|
||||
PutOperation(operation *Operation) error
|
||||
DeleteOperation(operationID string) error
|
||||
GetOperations() (map[string]*Operation, error)
|
||||
GetOperationByID(operationID string) (*Operation, error)
|
||||
}
|
||||
|
||||
type LevelDBState struct {
|
||||
sync.Mutex
|
||||
stateDb *leveldb.DB
|
||||
}
|
||||
|
||||
func NewLevelDBState(stateDbPath string) (State, error) {
|
||||
db, err := leveldb.OpenFile(stateDbPath, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open stateDB: %w", err)
|
||||
}
|
||||
|
||||
state := &LevelDBState{
|
||||
stateDb: db,
|
||||
}
|
||||
|
||||
if err := state.initKey(operationsKey, map[string]*Operation{}); err != nil {
|
||||
return nil, fmt.Errorf("failed to init %s storage: %w", operationsKey, err)
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) initKey(key string, data interface{}) error {
|
||||
if _, err := s.stateDb.Get([]byte(key), nil); err != nil {
|
||||
operationsBz, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal storage structure: %w", err)
|
||||
}
|
||||
err = s.stateDb.Put([]byte(key), operationsBz, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to init state: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) SaveOffset(offset uint64) error {
|
||||
bz := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(bz, offset)
|
||||
|
||||
if err := s.stateDb.Put([]byte(offsetKey), bz, nil); err != nil {
|
||||
return fmt.Errorf("failed to set offset: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) LoadOffset() (uint64, error) {
|
||||
bz, err := s.stateDb.Get([]byte(offsetKey), nil)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read offset: %w", err)
|
||||
}
|
||||
|
||||
offset := binary.LittleEndian.Uint64(bz)
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// TODO: implement.
|
||||
func (s *LevelDBState) SaveFSM(interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: implement.
|
||||
func (s *LevelDBState) LoadFSM() (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) PutOperation(operation *Operation) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
operations, err := s.getOperations()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to getOperations: %w", err)
|
||||
}
|
||||
|
||||
if _, ok := operations[operation.ID]; ok {
|
||||
return fmt.Errorf("operation %s already exists", operation.ID)
|
||||
}
|
||||
|
||||
operations[operation.ID] = operation
|
||||
operationsJSON, err := json.Marshal(operations)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal operations: %w", err)
|
||||
}
|
||||
|
||||
if err := s.stateDb.Put([]byte(operationsKey), operationsJSON, nil); err != nil {
|
||||
return fmt.Errorf("failed to put operations: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) DeleteOperation(operationID string) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
operations, err := s.getOperations()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to getOperations: %w", err)
|
||||
}
|
||||
|
||||
delete(operations, operationID)
|
||||
|
||||
operationsJSON, err := json.Marshal(operations)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal operations: %w", err)
|
||||
}
|
||||
|
||||
if err := s.stateDb.Put([]byte(operationsKey), operationsJSON, nil); err != nil {
|
||||
return fmt.Errorf("failed to put operations: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) GetOperations() (map[string]*Operation, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
return s.getOperations()
|
||||
}
|
||||
|
||||
func (s *LevelDBState) GetOperationByID(operationID string) (*Operation, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
operations, err := s.getOperations()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to getOperations: %w", err)
|
||||
}
|
||||
|
||||
operation, ok := operations[operationID]
|
||||
if !ok {
|
||||
return nil, errors.New("operation not found")
|
||||
}
|
||||
|
||||
return operation, nil
|
||||
}
|
||||
|
||||
func (s *LevelDBState) getOperations() (map[string]*Operation, error) {
|
||||
bz, err := s.stateDb.Get([]byte(operationsKey), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get Operations (key: %s): %w", operationsKey, err)
|
||||
}
|
||||
|
||||
var operations map[string]*Operation
|
||||
if err := json.Unmarshal(bz, &operations); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal Operations: %w", err)
|
||||
}
|
||||
|
||||
return operations, nil
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package client_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/p2p-org/dc4bc/client"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLevelDBState_SaveOffset(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
dbPath = "/tmp/dc4bc_test_SaveOffset"
|
||||
)
|
||||
defer os.RemoveAll(dbPath)
|
||||
|
||||
stg, err := client.NewLevelDBState(dbPath)
|
||||
req.NoError(err)
|
||||
|
||||
var offset uint64 = 1
|
||||
err = stg.SaveOffset(offset)
|
||||
req.NoError(err)
|
||||
|
||||
loadedOffset, err := stg.LoadOffset()
|
||||
req.NoError(err)
|
||||
req.Equal(offset, loadedOffset)
|
||||
}
|
||||
|
||||
func TestLevelDBState_PutOperation(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
dbPath = "/tmp/dc4bc_test_PutOperation"
|
||||
)
|
||||
defer os.RemoveAll(dbPath)
|
||||
|
||||
stg, err := client.NewLevelDBState(dbPath)
|
||||
req.NoError(err)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
Result: []byte("operation_result"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
err = stg.PutOperation(operation)
|
||||
req.NoError(err)
|
||||
|
||||
loadedOperation, err := stg.GetOperationByID(operation.ID)
|
||||
req.NoError(err)
|
||||
req.Equal(operation.ID, loadedOperation.ID)
|
||||
req.Equal(operation.Type, loadedOperation.Type)
|
||||
req.Equal(operation.Payload, loadedOperation.Payload)
|
||||
req.Equal(operation.Result, loadedOperation.Result)
|
||||
|
||||
err = stg.PutOperation(operation)
|
||||
req.Error(err)
|
||||
}
|
||||
|
||||
func TestLevelDBState_GetOperations(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
dbPath = "/tmp/dc4bc_test_PutOperation"
|
||||
)
|
||||
defer os.RemoveAll(dbPath)
|
||||
|
||||
stg, err := client.NewLevelDBState(dbPath)
|
||||
req.NoError(err)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_1",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
Result: []byte("operation_result"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
err = stg.PutOperation(operation)
|
||||
req.NoError(err)
|
||||
|
||||
operation.ID = "operation_2"
|
||||
err = stg.PutOperation(operation)
|
||||
req.NoError(err)
|
||||
|
||||
operations, err := stg.GetOperations()
|
||||
req.NoError(err)
|
||||
req.Len(operations, 2)
|
||||
}
|
||||
|
||||
func TestLevelDBState_DeleteOperation(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
dbPath = "/tmp/dc4bc_test_DeleteOperation"
|
||||
)
|
||||
defer os.RemoveAll(dbPath)
|
||||
|
||||
stg, err := client.NewLevelDBState(dbPath)
|
||||
req.NoError(err)
|
||||
|
||||
operation := &client.Operation{
|
||||
ID: "operation_id",
|
||||
Type: client.DKGCommits,
|
||||
Payload: []byte("operation_payload"),
|
||||
Result: []byte("operation_result"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
err = stg.PutOperation(operation)
|
||||
req.NoError(err)
|
||||
|
||||
_, err = stg.GetOperationByID(operation.ID)
|
||||
req.NoError(err)
|
||||
|
||||
err = stg.DeleteOperation(operation.ID)
|
||||
req.NoError(err)
|
||||
|
||||
_, err = stg.GetOperationByID(operation.ID)
|
||||
req.Error(err)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OperationType string
|
||||
|
||||
const (
|
||||
DKGCommits OperationType = "dkg_commits"
|
||||
)
|
||||
|
||||
type Operation struct {
|
||||
ID string // UUID4
|
||||
Type OperationType
|
||||
Payload []byte
|
||||
Result []byte
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (o *Operation) Check(o2 *Operation) error {
|
||||
if o.ID != o2.ID {
|
||||
return fmt.Errorf("o1.ID (%s) != o2.ID (%s)", o.ID, o2.ID)
|
||||
}
|
||||
|
||||
if o.Type != o2.Type {
|
||||
return fmt.Errorf("o1.Type (%s) != o2.Type (%s)", o.Type, o2.Type)
|
||||
}
|
||||
|
||||
if !bytes.Equal(o.Payload, o2.Payload) {
|
||||
return fmt.Errorf("o1.Payload (%v) != o2.Payload (%v)", o.Payload, o2.Payload)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -23,7 +23,7 @@ const (
|
|||
StateGlobalDone = "__done"
|
||||
)
|
||||
|
||||
// FSMResponse returns result for processing with client events
|
||||
// FSMResponse returns result for processing with clientMocks events
|
||||
type FSMResponse struct {
|
||||
// Returns machine execution result state
|
||||
State string
|
||||
|
|
18
go.mod
18
go.mod
|
@ -1,23 +1,25 @@
|
|||
module p2p.org/dc4bc
|
||||
module github.com/p2p-org/dc4bc
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b
|
||||
github.com/looplab/fsm v0.1.0
|
||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7
|
||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5
|
||||
github.com/p2p-org/dc4bc v0.0.0-00010101000000-000000000000
|
||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
go.dedis.ch/kyber/v3 v3.0.9
|
||||
gocv.io/x/gocv v0.23.0
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
|
||||
)
|
||||
|
||||
replace golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5
|
||||
|
||||
replace go.dedis.ch/kyber/v3 => github.com/corestario/kyber/v3 v3.0.0-20200218082721-8ed10c357c05
|
||||
|
||||
replace github.com/p2p-org/dc4bc => /home/tellme/PROJECTS/go/src/github.com/p2p-org/dc4bc
|
||||
replace (
|
||||
go.dedis.ch/kyber/v3 => github.com/corestario/kyber/v3 v3.0.0-20200218082721-8ed10c357c05
|
||||
golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5
|
||||
)
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
github.com/corestario/kyber/v3 v3.0.0-20200218082721-8ed10c357c05 h1:ICuDs+sbQzDem2pIAFyI+u6s0RiETzMc2IhnobgHkvE=
|
||||
github.com/corestario/kyber/v3 v3.0.0-20200218082721-8ed10c357c05/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b h1:FQ7+9fxhyp82ks9vAuyPzG0/vVbWwMwLJ+P6yJI5FN8=
|
||||
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b/go.mod h1:HMcgvsgd0Fjj4XXDkbjdmlbI505rUPBs6WBMYg2pXks=
|
||||
github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
|
||||
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
|
||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7 h1:CfWnkHgRG8zmxQI7RAhLIUFPkg+RfDdWiEtoE3y1+4w=
|
||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7/go.mod h1:WoI7z45M7ZNA5BJxiJHaB+x7+k8S/3phW5Y13IR4yWY=
|
||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5 h1:GMB3MVJnxysGrSvjWGsgK8L3XGI3F4etQQq37Py6W5A=
|
||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
|
||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f h1:QTRRO+ozoYgT3CQRIzNVYJRU3DB8HRnkZv6mr4ISmMA=
|
||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 h1:u8i49c+BxloX3XQ55cvzFNXplizZP/q00i+IlttUjAU=
|
||||
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
|
||||
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
|
||||
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
|
||||
go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo=
|
||||
go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4=
|
||||
gocv.io/x/gocv v0.23.0 h1:3Fgbt06/uR8Zf9emWndhjbUjdrw+nto69R/b4noFydY=
|
||||
gocv.io/x/gocv v0.23.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI=
|
||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
7
main.go
7
main.go
|
@ -2,14 +2,15 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen"
|
||||
_ "image/jpeg"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen"
|
||||
|
||||
"go.dedis.ch/kyber/v3"
|
||||
|
||||
dkglib "p2p.org/dc4bc/dkg"
|
||||
dkglib "github.com/p2p-org/dc4bc/dkg"
|
||||
|
||||
_ "image/gif"
|
||||
_ "image/png"
|
||||
|
@ -162,7 +163,7 @@ func runStep(transport *Transport, cb func(participantID string, participant *dk
|
|||
// log.Println("Please center the photo of the QR-code in front" +
|
||||
// "of your web-camera...")
|
||||
//
|
||||
// scannedData, err = qr.ReadQRFromCamera()
|
||||
// scannedData, err = qr.ReadQR()
|
||||
// if err == nil {
|
||||
// break
|
||||
// }
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: ./../client/state.go
|
||||
|
||||
// Package clientMocks is a generated GoMock package.
|
||||
package clientMocks
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
client "github.com/p2p-org/dc4bc/client"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockState is a mock of State interface
|
||||
type MockState struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStateMockRecorder
|
||||
}
|
||||
|
||||
// MockStateMockRecorder is the mock recorder for MockState
|
||||
type MockStateMockRecorder struct {
|
||||
mock *MockState
|
||||
}
|
||||
|
||||
// NewMockState creates a new mock instance
|
||||
func NewMockState(ctrl *gomock.Controller) *MockState {
|
||||
mock := &MockState{ctrl: ctrl}
|
||||
mock.recorder = &MockStateMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockState) EXPECT() *MockStateMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// SaveOffset mocks base method
|
||||
func (m *MockState) SaveOffset(arg0 uint64) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SaveOffset", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SaveOffset indicates an expected call of SaveOffset
|
||||
func (mr *MockStateMockRecorder) SaveOffset(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOffset", reflect.TypeOf((*MockState)(nil).SaveOffset), arg0)
|
||||
}
|
||||
|
||||
// LoadOffset mocks base method
|
||||
func (m *MockState) LoadOffset() (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "LoadOffset")
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// LoadOffset indicates an expected call of LoadOffset
|
||||
func (mr *MockStateMockRecorder) LoadOffset() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOffset", reflect.TypeOf((*MockState)(nil).LoadOffset))
|
||||
}
|
||||
|
||||
// SaveFSM mocks base method
|
||||
func (m *MockState) SaveFSM(arg0 interface{}) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SaveFSM", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SaveFSM indicates an expected call of SaveFSM
|
||||
func (mr *MockStateMockRecorder) SaveFSM(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveFSM", reflect.TypeOf((*MockState)(nil).SaveFSM), arg0)
|
||||
}
|
||||
|
||||
// LoadFSM mocks base method
|
||||
func (m *MockState) LoadFSM() (interface{}, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "LoadFSM")
|
||||
ret0, _ := ret[0].(interface{})
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// LoadFSM indicates an expected call of LoadFSM
|
||||
func (mr *MockStateMockRecorder) LoadFSM() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadFSM", reflect.TypeOf((*MockState)(nil).LoadFSM))
|
||||
}
|
||||
|
||||
// PutOperation mocks base method
|
||||
func (m *MockState) PutOperation(operation *client.Operation) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PutOperation", operation)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PutOperation indicates an expected call of PutOperation
|
||||
func (mr *MockStateMockRecorder) PutOperation(operation interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutOperation", reflect.TypeOf((*MockState)(nil).PutOperation), operation)
|
||||
}
|
||||
|
||||
// DeleteOperation mocks base method
|
||||
func (m *MockState) DeleteOperation(operationID string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteOperation", operationID)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteOperation indicates an expected call of DeleteOperation
|
||||
func (mr *MockStateMockRecorder) DeleteOperation(operationID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOperation", reflect.TypeOf((*MockState)(nil).DeleteOperation), operationID)
|
||||
}
|
||||
|
||||
// GetOperations mocks base method
|
||||
func (m *MockState) GetOperations() (map[string]*client.Operation, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetOperations")
|
||||
ret0, _ := ret[0].(map[string]*client.Operation)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetOperations indicates an expected call of GetOperations
|
||||
func (mr *MockStateMockRecorder) GetOperations() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperations", reflect.TypeOf((*MockState)(nil).GetOperations))
|
||||
}
|
||||
|
||||
// GetOperationByID mocks base method
|
||||
func (m *MockState) GetOperationByID(operationID string) (*client.Operation, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetOperationByID", operationID)
|
||||
ret0, _ := ret[0].(*client.Operation)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetOperationByID indicates an expected call of GetOperationByID
|
||||
func (mr *MockStateMockRecorder) GetOperationByID(operationID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperationByID", reflect.TypeOf((*MockState)(nil).GetOperationByID), operationID)
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package mocks
|
||||
|
||||
//go:generate mockgen -source=./../client/state.go -destination=./clientMocks/state_mock.go -package=clientMocks
|
||||
//go:generate mockgen -source=./../storage/types.go -destination=./storageMocks/storage_mock.go -package=storageMocks
|
||||
//go:generate mockgen -source=./../qr/qr.go -destination=./qrMocks/qr_mock.go -package=qrMocks
|
|
@ -0,0 +1,62 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: ./../qr/qr.go
|
||||
|
||||
// Package qrMocks is a generated GoMock package.
|
||||
package qrMocks
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockProcessor is a mock of Processor interface
|
||||
type MockProcessor struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockProcessorMockRecorder
|
||||
}
|
||||
|
||||
// MockProcessorMockRecorder is the mock recorder for MockProcessor
|
||||
type MockProcessorMockRecorder struct {
|
||||
mock *MockProcessor
|
||||
}
|
||||
|
||||
// NewMockProcessor creates a new mock instance
|
||||
func NewMockProcessor(ctrl *gomock.Controller) *MockProcessor {
|
||||
mock := &MockProcessor{ctrl: ctrl}
|
||||
mock.recorder = &MockProcessorMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockProcessor) EXPECT() *MockProcessorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// ReadQR mocks base method
|
||||
func (m *MockProcessor) ReadQR() ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReadQR")
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ReadQR indicates an expected call of ReadQR
|
||||
func (mr *MockProcessorMockRecorder) ReadQR() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadQR", reflect.TypeOf((*MockProcessor)(nil).ReadQR))
|
||||
}
|
||||
|
||||
// WriteQR mocks base method
|
||||
func (m *MockProcessor) WriteQR(path string, data []byte) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "WriteQR", path, data)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// WriteQR indicates an expected call of WriteQR
|
||||
func (mr *MockProcessorMockRecorder) WriteQR(path, data interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteQR", reflect.TypeOf((*MockProcessor)(nil).WriteQR), path, data)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: ./../storage/types.go
|
||||
|
||||
// Package storageMocks is a generated GoMock package.
|
||||
package storageMocks
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
storage "github.com/p2p-org/dc4bc/storage"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockStorage is a mock of Storage interface
|
||||
type MockStorage struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStorageMockRecorder
|
||||
}
|
||||
|
||||
// MockStorageMockRecorder is the mock recorder for MockStorage
|
||||
type MockStorageMockRecorder struct {
|
||||
mock *MockStorage
|
||||
}
|
||||
|
||||
// NewMockStorage creates a new mock instance
|
||||
func NewMockStorage(ctrl *gomock.Controller) *MockStorage {
|
||||
mock := &MockStorage{ctrl: ctrl}
|
||||
mock.recorder = &MockStorageMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockStorage) EXPECT() *MockStorageMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Send mocks base method
|
||||
func (m *MockStorage) Send(message storage.Message) (storage.Message, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Send", message)
|
||||
ret0, _ := ret[0].(storage.Message)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send
|
||||
func (mr *MockStorageMockRecorder) Send(message interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockStorage)(nil).Send), message)
|
||||
}
|
||||
|
||||
// GetMessages mocks base method
|
||||
func (m *MockStorage) GetMessages(offset uint64) ([]storage.Message, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMessages", offset)
|
||||
ret0, _ := ret[0].([]storage.Message)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetMessages indicates an expected call of GetMessages
|
||||
func (mr *MockStorageMockRecorder) GetMessages(offset interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessages", reflect.TypeOf((*MockStorage)(nil).GetMessages), offset)
|
||||
}
|
||||
|
||||
// Close mocks base method
|
||||
func (m *MockStorage) Close() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Close")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Close indicates an expected call of Close
|
||||
func (mr *MockStorageMockRecorder) Close() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStorage)(nil).Close))
|
||||
}
|
|
@ -5,6 +5,8 @@ import (
|
|||
"log"
|
||||
"time"
|
||||
|
||||
encoder "github.com/skip2/go-qrcode"
|
||||
|
||||
"github.com/makiuchi-d/gozxing"
|
||||
"github.com/makiuchi-d/gozxing/qrcode"
|
||||
"gocv.io/x/gocv"
|
||||
|
@ -12,10 +14,21 @@ import (
|
|||
|
||||
const timeToScan = time.Second * 5
|
||||
|
||||
func ReadQRFromCamera() (string, error) {
|
||||
type Processor interface {
|
||||
ReadQR() ([]byte, error)
|
||||
WriteQR(path string, data []byte) error
|
||||
}
|
||||
|
||||
type CameraProcessor struct{}
|
||||
|
||||
func NewCameraProcessor() *CameraProcessor {
|
||||
return &CameraProcessor{}
|
||||
}
|
||||
|
||||
func (p *CameraProcessor) ReadQR() ([]byte, error) {
|
||||
webcam, err := gocv.OpenVideoCapture(0)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to OpenVideoCapture: %w", err)
|
||||
return nil, fmt.Errorf("failed to OpenVideoCapture: %w", err)
|
||||
}
|
||||
window := gocv.NewWindow("Hello")
|
||||
|
||||
|
@ -50,19 +63,28 @@ loop:
|
|||
|
||||
imgObject, err := img.ToImage()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get image object: %w", err)
|
||||
return nil, fmt.Errorf("failed to get image object: %w", err)
|
||||
}
|
||||
|
||||
bmp, err := gozxing.NewBinaryBitmapFromImage(imgObject)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get NewBinaryBitmapFromImage: %w", err)
|
||||
return nil, fmt.Errorf("failed to get NewBinaryBitmapFromImage: %w", err)
|
||||
}
|
||||
|
||||
qrReader := qrcode.NewQRCodeReader()
|
||||
result, err := qrReader.Decode(bmp, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode the QR-code contents: %w", err)
|
||||
return nil, fmt.Errorf("failed to decode the QR-code contents: %w", err)
|
||||
}
|
||||
|
||||
return result.String(), err
|
||||
return result.GetRawBytes(), err
|
||||
}
|
||||
|
||||
func (p *CameraProcessor) WriteQR(path string, data []byte) error {
|
||||
err := encoder.WriteFile(string(data), encoder.Medium, 512, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode the data: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package qr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
|
||||
encoder "github.com/skip2/go-qrcode"
|
||||
|
||||
_ "golang.org/x/image/bmp"
|
||||
_ "golang.org/x/image/tiff"
|
||||
)
|
||||
|
||||
const tmpImageFile = "/tmp/qr.png"
|
||||
|
||||
func ShowQR(data string) error {
|
||||
defer func() {
|
||||
_ = os.Remove(tmpImageFile)
|
||||
}()
|
||||
|
||||
err := encoder.WriteFile(data, encoder.Medium, 512, tmpImageFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode the data: %w", err)
|
||||
}
|
||||
|
||||
showImage(tmpImageFile)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func showImage(imageFile string) {
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("p2p.org QR Viewer")
|
||||
window.SetIconName("p2p.org QR Viewer")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
gtk.MainQuit()
|
||||
})
|
||||
|
||||
hbox := gtk.NewHBox(false, 1)
|
||||
hpaned := gtk.NewHPaned()
|
||||
hbox.Add(hpaned)
|
||||
frame1 := gtk.NewFrame("QR Code")
|
||||
framebox1 := gtk.NewHBox(false, 1)
|
||||
frame1.Add(framebox1)
|
||||
hpaned.Pack1(frame1, false, false)
|
||||
image := gtk.NewImageFromFile(imageFile)
|
||||
framebox1.Add(image)
|
||||
window.Add(hbox)
|
||||
imagePixBuffer := image.GetPixbuf()
|
||||
horizontalSize := imagePixBuffer.GetWidth()
|
||||
verticalSize := imagePixBuffer.GetHeight()
|
||||
|
||||
window.SetSizeRequest(horizontalSize, verticalSize)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
|
@ -4,10 +4,11 @@ import (
|
|||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"github.com/juju/fslock"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/juju/fslock"
|
||||
)
|
||||
|
||||
var _ Storage = (*FileStorage)(nil)
|
||||
|
@ -81,7 +82,7 @@ func (fs *FileStorage) Send(m Message) (Message, error) {
|
|||
}
|
||||
|
||||
// GetMessages returns a slice of messages from append-only data file with given offset
|
||||
func (fs *FileStorage) GetMessages(offset int) ([]Message, error) {
|
||||
func (fs *FileStorage) GetMessages(offset uint64) ([]Message, error) {
|
||||
var (
|
||||
msgs []Message
|
||||
err error
|
||||
|
|
|
@ -2,6 +2,7 @@ package storage
|
|||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -18,12 +19,15 @@ func randomBytes(n int) []byte {
|
|||
|
||||
func TestFileStorage_GetMessages(t *testing.T) {
|
||||
N := 10
|
||||
offset := 5
|
||||
fs, err := InitFileStorage("test")
|
||||
var offset uint64 = 5
|
||||
var testFile = "/tmp/dc4bc_test_file_storage"
|
||||
fs, err := InitFileStorage(testFile)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer os.Remove(testFile)
|
||||
|
||||
msgs := make([]Message, 0, N)
|
||||
for i := 0; i < N; i++ {
|
||||
msg := Message{
|
||||
|
@ -36,10 +40,12 @@ func TestFileStorage_GetMessages(t *testing.T) {
|
|||
}
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
offsetMsgs, err := fs.GetMessages(offset)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expectedOffsetMsgs := msgs[offset:]
|
||||
if !reflect.DeepEqual(offsetMsgs, expectedOffsetMsgs) {
|
||||
t.Errorf("expected messages: %v, actual messages: %v", expectedOffsetMsgs, offsetMsgs)
|
||||
|
|
|
@ -9,6 +9,6 @@ type Message struct {
|
|||
|
||||
type Storage interface {
|
||||
Send(message Message) (Message, error)
|
||||
GetMessages(offset int) ([]Message, error)
|
||||
GetMessages(offset uint64) ([]Message, error)
|
||||
Close() error
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue