From 989dcf40e14f58f555c1f48ec43d01a6dcce6f20 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 28 Mar 2019 07:31:26 +0300 Subject: [PATCH 01/26] Unsure --- pkg/transport/manager.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index c214da842f..5341515319 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -198,7 +198,8 @@ func (tm *Manager) Serve(ctx context.Context) error { // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { - return tm.createTransport(ctx, remote, tpType, uuid.UUID{}, public) + uid := uuid.NewSHA1(uuid.UUID{}, []byte(remote.Hex())) + return tm.createTransport(ctx, remote, tpType, uid, public) } // DeleteTransport disconnects and removes the Transport of Transport ID. From 5fa0d6e91c23f4daf2b986b11bb7e0394c6218ff Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 28 Mar 2019 11:38:07 +0300 Subject: [PATCH 02/26] Changes: 1. `make test` exclude pkg/messaging from data races testing - it's already confirmed that we have problems here --- Makefile | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6a1f78bdb8..4510e55e0b 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,22 @@ vendorcheck: ## Run vendorcheck #GO111MODULE=off vendorcheck ./cmd/therealssh-cli/... test: ## Run tests for net + -go clean -testcache ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./internal/... - ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/... + #${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/app/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/cipher/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/manager/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/messaging-discovery/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/node/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/route-finder/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/router/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/routing/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/setup/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/transport/... + ${OPTS} go test -race -tags no_ci -cover -timeout=5m ./pkg/transport-discovery/... + ${OPTS} go test -tags no_ci -cover -timeout=5m ./pkg/messaging/... + install-linters: ## Install linters - VERSION=1.13.2 ./ci_scripts/install-golangci-lint.sh From 65f602e679293eb315d327720c40446eada74dfd Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 28 Mar 2019 12:18:25 +0300 Subject: [PATCH 03/26] Changes: 1. pkg/transport/manager.go: CreateTransport uses both local and remote pks for uuid of transport --- pkg/transport/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 5341515319..93ecf38bee 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -198,7 +198,7 @@ func (tm *Manager) Serve(ctx context.Context) error { // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { - uid := uuid.NewSHA1(uuid.UUID{}, []byte(remote.Hex())) + uid := uuid.NewSHA1(uuid.UUID{}, append(tm.config.PubKey[:], remote[:]...)) return tm.createTransport(ctx, remote, tpType, uid, public) } From c1dc372655d380d05e3eb0558ab55650757b7439 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Fri, 29 Mar 2019 12:20:58 +0300 Subject: [PATCH 04/26] Working but with data races --- pkg/transport/manager.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 93ecf38bee..fa6b5a9f0c 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -326,9 +326,17 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag } tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), tr.Remote(), entry.ID) - managedTr := newManagedTransport(entry.ID, tr, entry.Public) + tm.mu.Lock() - tm.transports[entry.ID] = managedTr + rpk, lpk := tr.Remote(), tr.Local() + uid := uuid.NewSHA1(uuid.UUID{}, append(lpk[:], rpk[:]...)) + managedTr := newManagedTransport(uid, tr, entry.Public) + + if existingTr, ok := tm.transports[uid]; ok { + return existingTr, nil + } + + tm.transports[uid] = managedTr select { case <-tm.doneChan: case tm.acceptedTrChan <- managedTr: @@ -346,7 +354,7 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return case err := <-managedTr.errChan: tm.Logger.Infof("Transport %s failed with error: %s. Re-dialing...", managedTr.ID, err) - if err := tm.DeleteTransport(entry.ID); err != nil { + if err := tm.DeleteTransport(uid); err != nil { tm.Logger.Warnf("Failed to delete transport: %s", err) } } From 2e8a2da4313eb68bee47afd67a08f85f95d311e6 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Fri, 29 Mar 2019 19:58:14 +0300 Subject: [PATCH 05/26] Changes: 1. Implemented transport.GetTransportUUID function that creates namesplace-based uuid.UUID from pair of cipher.Pubkey 2. This function is used instead of uuid.New() for creation IDs of Transports Result: - It passes all tests - But with manual check it breaks on https://github.com/skycoin/skywire/blob/c1dc372655d380d05e3eb0558ab55650757b7439/pkg/transport/manager.go#L166 --- pkg/node/rpc_client.go | 4 +-- pkg/route-finder/client/mock.go | 9 +++--- pkg/transport-discovery/client/client_test.go | 3 +- pkg/transport/handshake.go | 3 +- pkg/transport/handshake_test.go | 2 +- pkg/transport/manager.go | 30 +++++++++++-------- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/pkg/node/rpc_client.go b/pkg/node/rpc_client.go index 033e75656b..c98e51b82f 100644 --- a/pkg/node/rpc_client.go +++ b/pkg/node/rpc_client.go @@ -153,7 +153,7 @@ func NewMockRPCClient(r *rand.Rand, maxTps int, maxRules int) (cipher.PubKey, RP for i := range tps { remotePK, _ := cipher.GenerateKeyPair() tps[i] = &TransportSummary{ - ID: uuid.New(), + ID: transport.GetTransportUUID(localPK, remotePK), Local: localPK, Remote: remotePK, Type: types[r.Int()%len(types)], @@ -314,7 +314,7 @@ func (mc *mockRPCClient) Transport(tid uuid.UUID) (*TransportSummary, error) { // AddTransport implements RPCClient. func (mc *mockRPCClient) AddTransport(remote cipher.PubKey, tpType string, public bool, _ time.Duration) (*TransportSummary, error) { summary := &TransportSummary{ - ID: uuid.New(), + ID: transport.GetTransportUUID(mc.s.PubKey, remote), Local: mc.s.PubKey, Remote: remote, Type: tpType, diff --git a/pkg/route-finder/client/mock.go b/pkg/route-finder/client/mock.go index 25b2ace7b9..f893db3b4f 100644 --- a/pkg/route-finder/client/mock.go +++ b/pkg/route-finder/client/mock.go @@ -1,10 +1,9 @@ package client import ( - "github.com/google/uuid" - "github.com/skycoin/skywire/pkg/cipher" "github.com/skycoin/skywire/pkg/routing" + "github.com/skycoin/skywire/pkg/transport" ) // MockClient implements mock route finder client. @@ -23,7 +22,7 @@ func (r *mockClient) SetError(err error) { r.err = err } -// PairedRoutes implements Clien for MockClient +// PairedRoutes implements Client for MockClient func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint16) ([]routing.Route, []routing.Route, error) { if r.err != nil { return nil, nil, r.err @@ -34,7 +33,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: uuid.New(), + Transport: transport.GetTransportUUID(src, dst), }, }, }, []routing.Route{ @@ -42,7 +41,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: uuid.New(), + Transport: transport.GetTransportUUID(src, dst), }, }, }, nil diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index 11dca0f009..2cfbfc8f30 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -10,7 +10,6 @@ import ( "sync" "testing" - "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -25,7 +24,7 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() return &transport.Entry{ - ID: uuid.New(), + ID: transport.GetTransportUUID(pk1, testPubKey), Edges: [2]cipher.PubKey{pk1, testPubKey}, Type: "messaging", Public: true, diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index dd784b4dff..21974bbb9f 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -41,7 +41,7 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake newEntry := id == uuid.UUID{} if newEntry { - entry.ID = uuid.New() + entry.ID = GetTransportUUID(tr.Local(), tr.Remote()) } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} @@ -76,6 +76,7 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { } sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) + newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil var err error diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index d22ab462a6..cd6067bba4 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -130,7 +130,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { require.NoError(t, err) entry := &Entry{ - ID: uuid.New(), + ID: GetTransportUUID(pk1, pk2), Edges: [2]cipher.PubKey{pk1, pk2}, Type: "mock", Public: true, diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index fa6b5a9f0c..bbe8e7fa30 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -196,10 +196,22 @@ func (tm *Manager) Serve(ctx context.Context) error { return nil } +// GenTransportUUID generates uuid.UUID from pair of keys +func GetTransportUUID(keyA, keyB cipher.PubKey) uuid.UUID { + var mixedKeys = make([]byte, 66) + for i := 0; i < 33; i++ { + if keyA[i] < keyB[i] { + mixedKeys[i*2], mixedKeys[i*2+1] = keyA[i], keyB[i] + } else { + mixedKeys[i*2], mixedKeys[i*2+1] = keyB[i], keyA[i] + } + } + return uuid.NewSHA1(uuid.UUID{}, mixedKeys) +} + // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { - uid := uuid.NewSHA1(uuid.UUID{}, append(tm.config.PubKey[:], remote[:]...)) - return tm.createTransport(ctx, remote, tpType, uid, public) + return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote), public) } // DeleteTransport disconnects and removes the Transport of Transport ID. @@ -326,17 +338,10 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag } tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), tr.Remote(), entry.ID) - + managedTr := newManagedTransport(entry.ID, tr, entry.Public) tm.mu.Lock() - rpk, lpk := tr.Remote(), tr.Local() - uid := uuid.NewSHA1(uuid.UUID{}, append(lpk[:], rpk[:]...)) - managedTr := newManagedTransport(uid, tr, entry.Public) - - if existingTr, ok := tm.transports[uid]; ok { - return existingTr, nil - } - tm.transports[uid] = managedTr + tm.transports[entry.ID] = managedTr select { case <-tm.doneChan: case tm.acceptedTrChan <- managedTr: @@ -344,6 +349,7 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag } tm.mu.Unlock() + // go func(managedTr *ManagedTransport, tm *Manager) { go func() { select { case <-managedTr.doneChan: @@ -354,7 +360,7 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return case err := <-managedTr.errChan: tm.Logger.Infof("Transport %s failed with error: %s. Re-dialing...", managedTr.ID, err) - if err := tm.DeleteTransport(uid); err != nil { + if err := tm.DeleteTransport(managedTr.ID); err != nil { tm.Logger.Warnf("Failed to delete transport: %s", err) } } From 5729dc5fc8f37b3f34fe5e606d209fd7b82f2f2f Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 1 Apr 2019 12:51:53 +0300 Subject: [PATCH 06/26] Changes: 1. Fixed calculation of Entry.ID in GetTransportUUID 2. Added Example for GetTransportUUID --- pkg/transport/manager.go | 18 +++++++++++------- pkg/transport/manager_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index bbe8e7fa30..efaf80e5ba 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -196,17 +196,21 @@ func (tm *Manager) Serve(ctx context.Context) error { return nil } -// GenTransportUUID generates uuid.UUID from pair of keys +// GetTransportUUID generates uuid.UUID from pair of keys. +// Generated uuid is: +// - always the same for a given pair +// - GenTransportUUID(keyA,keyB) == GenTransportUUID(keyB, keyA) func GetTransportUUID(keyA, keyB cipher.PubKey) uuid.UUID { - var mixedKeys = make([]byte, 66) for i := 0; i < 33; i++ { - if keyA[i] < keyB[i] { - mixedKeys[i*2], mixedKeys[i*2+1] = keyA[i], keyB[i] - } else { - mixedKeys[i*2], mixedKeys[i*2+1] = keyB[i], keyA[i] + if keyA[i] != keyB[i] { + if keyA[i] < keyB[i] { + return uuid.NewSHA1(uuid.UUID{}, append(keyA[:], keyB[:]...)) + } else { + return uuid.NewSHA1(uuid.UUID{}, append(keyB[:], keyA[:]...)) + } } } - return uuid.NewSHA1(uuid.UUID{}, mixedKeys) + return uuid.NewSHA1(uuid.UUID{}, append(keyA[:], keyB[:]...)) } // CreateTransport begins to attempt to establish transports to the given 'remote' node. diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index c8e9bc1a5e..fbd018a25f 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -2,6 +2,7 @@ package transport import ( "context" + "fmt" "io" "sync" "testing" @@ -211,3 +212,35 @@ func TestTransportManagerLogs(t *testing.T) { require.NoError(t, m1.Close()) require.NoError(t, <-errCh) } + +// GetTransportUUID(keyA,keyB) == GetTransportUUID(keyB, keyA) +// GetTrasportUUID(keyA,keyB) is always the same for a given pair +// GetTransportUUID(keyA, keyA) works for equal keys +func ExampleGetTransportUUID() { + keyA, _ := cipher.GenerateKeyPair() + keyB, _ := cipher.GenerateKeyPair() + + uuidAB := GetTransportUUID(keyA, keyB) + + for i := 0; i < 256; i++ { + if GetTransportUUID(keyA, keyB) != uuidAB { + fmt.Printf("uuid is unstable") + break + } + } + fmt.Printf("uuid is stable\n") + + uuidBA := GetTransportUUID(keyB, keyA) + if uuidAB == uuidBA { + fmt.Printf("uuid is bidirectional\n") + } else { + fmt.Printf("keyA = %v\n keyB=%v\n uuidAB=%v\n uuidBA=%v\n", keyA, keyB, uuidAB, uuidBA) + } + + _ = GetTransportUUID(keyA, keyA) // works for equal keys + fmt.Printf("works for equal keys") + + // Output: uuid is stable + // uuid is bidirectional + // works for equal keys +} From 764be58e67a75b5deedd40cb28ab6e289393886a Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 1 Apr 2019 16:07:45 +0300 Subject: [PATCH 07/26] Changes: 1. pkg/transport/manager.go: changed calculation of Entry.ID now it takes sorted keys + tpType for GetTransportUUID 2. manager_test.go: Changed ExampleGetTransportUUID 3. mock.go - moved mockTransportManagers from rpc_test.go and made public 4. Others: changed accordingly to modifications above Result: Now it breaks in some tests with probability 50% - which is expected. --- pkg/node/rpc_client.go | 4 +- pkg/node/rpc_test.go | 31 +------------ pkg/route-finder/client/mock.go | 4 +- pkg/transport-discovery/client/client_test.go | 5 +- pkg/transport/handshake.go | 4 +- pkg/transport/handshake_test.go | 2 +- pkg/transport/manager.go | 16 +++++-- pkg/transport/manager_test.go | 46 ++++++++++++++++--- pkg/transport/mock.go | 27 +++++++++++ 9 files changed, 89 insertions(+), 50 deletions(-) diff --git a/pkg/node/rpc_client.go b/pkg/node/rpc_client.go index c98e51b82f..334f67fb1a 100644 --- a/pkg/node/rpc_client.go +++ b/pkg/node/rpc_client.go @@ -153,7 +153,7 @@ func NewMockRPCClient(r *rand.Rand, maxTps int, maxRules int) (cipher.PubKey, RP for i := range tps { remotePK, _ := cipher.GenerateKeyPair() tps[i] = &TransportSummary{ - ID: transport.GetTransportUUID(localPK, remotePK), + ID: transport.GetTransportUUID(localPK, remotePK, types[r.Int()%len(types)]), Local: localPK, Remote: remotePK, Type: types[r.Int()%len(types)], @@ -314,7 +314,7 @@ func (mc *mockRPCClient) Transport(tid uuid.UUID) (*TransportSummary, error) { // AddTransport implements RPCClient. func (mc *mockRPCClient) AddTransport(remote cipher.PubKey, tpType string, public bool, _ time.Duration) (*TransportSummary, error) { summary := &TransportSummary{ - ID: transport.GetTransportUUID(mc.s.PubKey, remote), + ID: transport.GetTransportUUID(mc.s.PubKey, remote, tpType), Local: mc.s.PubKey, Remote: remote, Type: tpType, diff --git a/pkg/node/rpc_test.go b/pkg/node/rpc_test.go index 26569791be..1d6e80ca4e 100644 --- a/pkg/node/rpc_test.go +++ b/pkg/node/rpc_test.go @@ -14,8 +14,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/skycoin/skywire/pkg/cipher" - "github.com/skycoin/skywire/pkg/routing" "github.com/skycoin/skywire/pkg/transport" ) @@ -88,39 +86,12 @@ func TestStartStopApp(t *testing.T) { node.startedMu.Unlock() } -func mockTransportManagers() (pk1, pk2 cipher.PubKey, m1, m2 *transport.Manager, errCh chan error, err error) { - discovery := transport.NewDiscoveryMock() - logs := transport.InMemoryTransportLogStore() - - var sk1, sk2 cipher.SecKey - pk1, sk1 = cipher.GenerateKeyPair() - pk2, sk2 = cipher.GenerateKeyPair() - - c1 := &transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: discovery, LogStore: logs} - c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: discovery, LogStore: logs} - - f1, f2 := transport.NewMockFactory(pk1, pk2) - - if m1, err = transport.NewManager(c1, f1); err != nil { - return - } - if m2, err = transport.NewManager(c2, f2); err != nil { - return - } - - errCh = make(chan error) - go func() { errCh <- m1.Serve(context.TODO()) }() - go func() { errCh <- m2.Serve(context.TODO()) }() - - return -} - func TestRPC(t *testing.T) { r := new(mockRouter) executer := new(MockExecuter) defer os.RemoveAll("chat") - pk1, _, tm1, tm2, errCh, err := mockTransportManagers() + pk1, _, tm1, tm2, errCh, err := transport.MockTransportManagers() require.NoError(t, err) defer func() { require.NoError(t, tm1.Close()) diff --git a/pkg/route-finder/client/mock.go b/pkg/route-finder/client/mock.go index f893db3b4f..6f36ce671f 100644 --- a/pkg/route-finder/client/mock.go +++ b/pkg/route-finder/client/mock.go @@ -33,7 +33,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.GetTransportUUID(src, dst), + Transport: transport.GetTransportUUID(src, dst, ""), }, }, }, []routing.Route{ @@ -41,7 +41,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.GetTransportUUID(src, dst), + Transport: transport.GetTransportUUID(src, dst, ""), }, }, }, nil diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index 2cfbfc8f30..8b35938eb7 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -23,10 +23,11 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() + tpType := "messaging" return &transport.Entry{ - ID: transport.GetTransportUUID(pk1, testPubKey), + ID: transport.GetTransportUUID(pk1, testPubKey, tpType), Edges: [2]cipher.PubKey{pk1, testPubKey}, - Type: "messaging", + Type: tpType, Public: true, } } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 21974bbb9f..4dcc09cd43 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -34,14 +34,14 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ ID: id, - Edges: [2]cipher.PubKey{tr.Local(), tr.Remote()}, + Edges: SortPubKeys(tr.Local(), tr.Remote()), Type: tr.Type(), Public: public, } newEntry := id == uuid.UUID{} if newEntry { - entry.ID = GetTransportUUID(tr.Local(), tr.Remote()) + entry.ID = GetTransportUUID(entry.Edges[0], entry.Edges[1], entry.Type) } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index cd6067bba4..fc213c2ca5 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -130,7 +130,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { require.NoError(t, err) entry := &Entry{ - ID: GetTransportUUID(pk1, pk2), + ID: GetTransportUUID(pk1, pk2, ""), Edges: [2]cipher.PubKey{pk1, pk2}, Type: "mock", Public: true, diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index efaf80e5ba..19ba514630 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -200,22 +200,28 @@ func (tm *Manager) Serve(ctx context.Context) error { // Generated uuid is: // - always the same for a given pair // - GenTransportUUID(keyA,keyB) == GenTransportUUID(keyB, keyA) -func GetTransportUUID(keyA, keyB cipher.PubKey) uuid.UUID { +func GetTransportUUID(keyA, keyB cipher.PubKey, tpType string) uuid.UUID { + keys := SortPubKeys(keyA, keyB) + return uuid.NewSHA1(uuid.UUID{}, append(append(keys[0][:], keys[1][:]...), []byte(tpType)...)) +} + +// SortPubKeys sorts keys so that least-significant comes first +func SortPubKeys(keyA, keyB cipher.PubKey) [2]cipher.PubKey { for i := 0; i < 33; i++ { if keyA[i] != keyB[i] { if keyA[i] < keyB[i] { - return uuid.NewSHA1(uuid.UUID{}, append(keyA[:], keyB[:]...)) + return [2]cipher.PubKey{keyA, keyB} } else { - return uuid.NewSHA1(uuid.UUID{}, append(keyB[:], keyA[:]...)) + return [2]cipher.PubKey{keyB, keyA} } } } - return uuid.NewSHA1(uuid.UUID{}, append(keyA[:], keyB[:]...)) + return [2]cipher.PubKey{keyA, keyB} } // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { - return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote), public) + return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote, tpType), public) } // DeleteTransport disconnects and removes the Transport of Transport ID. diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index fbd018a25f..7c9f3ae4c3 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -213,34 +213,68 @@ func TestTransportManagerLogs(t *testing.T) { require.NoError(t, <-errCh) } -// GetTransportUUID(keyA,keyB) == GetTransportUUID(keyB, keyA) +// GetTransportUUID(keyA,keyB, "type") == GetTransportUUID(keyB, keyA, "type") // GetTrasportUUID(keyA,keyB) is always the same for a given pair // GetTransportUUID(keyA, keyA) works for equal keys +// GetTransportUUID(keyA,keyB, "type") != GetTransportUUID(keyB, keyA, "type") func ExampleGetTransportUUID() { keyA, _ := cipher.GenerateKeyPair() keyB, _ := cipher.GenerateKeyPair() - uuidAB := GetTransportUUID(keyA, keyB) + uuidAB := GetTransportUUID(keyA, keyB, "type") for i := 0; i < 256; i++ { - if GetTransportUUID(keyA, keyB) != uuidAB { + if GetTransportUUID(keyA, keyB, "type") != uuidAB { fmt.Printf("uuid is unstable") break } } fmt.Printf("uuid is stable\n") - uuidBA := GetTransportUUID(keyB, keyA) + uuidBA := GetTransportUUID(keyB, keyA, "type") if uuidAB == uuidBA { fmt.Printf("uuid is bidirectional\n") } else { fmt.Printf("keyA = %v\n keyB=%v\n uuidAB=%v\n uuidBA=%v\n", keyA, keyB, uuidAB, uuidBA) } - _ = GetTransportUUID(keyA, keyA) // works for equal keys - fmt.Printf("works for equal keys") + _ = GetTransportUUID(keyA, keyA, "type") // works for equal keys + fmt.Printf("works for equal keys\n") + + if GetTransportUUID(keyA, keyB, "type") != GetTransportUUID(keyA, keyB, "another_type") { + fmt.Printf("uuid is different for different types") + } // Output: uuid is stable // uuid is bidirectional // works for equal keys + // uuid is different for different types +} + +func ExampleManagerCreateTransport() { + + + + // discovery := transport.NewDiscoveryMock() + // logs := transport.InMemoryTransportLogStore() + + // var sk1, sk2 cipher.SecKey + // pk1, sk1 = cipher.GenerateKeyPair() + // pk2, sk2 = cipher.GenerateKeyPair() + + // c1 := &transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: discovery, LogStore: logs} + // c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: discovery, LogStore: logs} + + // f1, f2 := transport.NewMockFactory(pk1, pk2) + + // if m1, err = transport.NewManager(c1, f1); err != nil { + // return + // } + // if m2, err = transport.NewManager(c2, f2); err != nil { + // return + // } + + // errCh = make(chan error) + // go func() { errCh <- m1.Serve(context.TODO()) }() + } diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index 7c6baf26bf..cbc50e5931 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -142,3 +142,30 @@ func (m *MockTransport) SetDeadline(t time.Time) error { func (m *MockTransport) Type() string { return "mock" } + +func MockTransportManagers() (pk1, pk2 cipher.PubKey, m1, m2 *Manager, errCh chan error, err error) { + discovery := NewDiscoveryMock() + logs := InMemoryTransportLogStore() + + var sk1, sk2 cipher.SecKey + pk1, sk1 = cipher.GenerateKeyPair() + pk2, sk2 = cipher.GenerateKeyPair() + + c1 := &ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: discovery, LogStore: logs} + c2 := &ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: discovery, LogStore: logs} + + f1, f2 := NewMockFactory(pk1, pk2) + + if m1, err = NewManager(c1, f1); err != nil { + return + } + if m2, err = NewManager(c2, f2); err != nil { + return + } + + errCh = make(chan error) + go func() { errCh <- m1.Serve(context.TODO()) }() + go func() { errCh <- m2.Serve(context.TODO()) }() + + return +} From 4751cd76b838e04ff9b682fcfe2505166d9d76ba Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 1 Apr 2019 17:27:49 +0300 Subject: [PATCH 08/26] Changes: 1. pkg/transport/mock.go: - renamed MockTransportManagers to MockTransportManagersPair - created MockTransportManager for testing Manager 2. pkg/transport/manager_test.go: created ExampleManagerCreateTransport Result: ExampleManagerCreateTransport fails as expected --- pkg/transport/manager_test.go | 47 +++++++++++++++++------------------ pkg/transport/mock.go | 15 ++++++++--- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 7c9f3ae4c3..ae3f42f1a6 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -24,7 +25,7 @@ func TestTransportManager(t *testing.T) { c1 := &ManagerConfig{pk1, sk1, client, logStore, nil} c2 := &ManagerConfig{pk2, sk2, client, logStore, nil} - f1, f2 := NewMockFactory(pk1, pk2) + f1, f2 := NewMockFactoryPair(pk1, pk2) m1, err := NewManager(c1, f1) require.NoError(t, err) @@ -112,7 +113,7 @@ func TestTransportManagerReEstablishTransports(t *testing.T) { c1 := &ManagerConfig{pk1, sk1, client, logStore, nil} c2 := &ManagerConfig{pk2, sk2, client, logStore, nil} - f1, f2 := NewMockFactory(pk1, pk2) + f1, f2 := NewMockFactoryPair(pk1, pk2) m1, err := NewManager(c1, f1) require.NoError(t, err) @@ -169,7 +170,7 @@ func TestTransportManagerLogs(t *testing.T) { c1 := &ManagerConfig{pk1, sk1, client, logStore1, nil} c2 := &ManagerConfig{pk2, sk2, client, logStore2, nil} - f1, f2 := NewMockFactory(pk1, pk2) + f1, f2 := NewMockFactoryPair(pk1, pk2) m1, err := NewManager(c1, f1) require.NoError(t, err) @@ -252,29 +253,27 @@ func ExampleGetTransportUUID() { } func ExampleManagerCreateTransport() { + // Repetition is required here to guarantee that correctness does not depends on order of edges + for i := 0; i < 256; i++ { + pkB, mgrA, err := MockTransportManager() + if err != nil { + fmt.Printf("MockTransportManager failed on iteration %v with: %v\n", i, err) + return + } - - - // discovery := transport.NewDiscoveryMock() - // logs := transport.InMemoryTransportLogStore() - - // var sk1, sk2 cipher.SecKey - // pk1, sk1 = cipher.GenerateKeyPair() - // pk2, sk2 = cipher.GenerateKeyPair() - - // c1 := &transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: discovery, LogStore: logs} - // c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: discovery, LogStore: logs} - - // f1, f2 := transport.NewMockFactory(pk1, pk2) + mtrAB, err := mgrA.CreateTransport(context.TODO(), pkB, "mock", true) + if err != nil { + fmt.Printf("Manager.CreateTransport failed on iteration %v with: %v\n", i, err) + return + } - // if m1, err = transport.NewManager(c1, f1); err != nil { - // return - // } - // if m2, err = transport.NewManager(c2, f2); err != nil { - // return - // } + if (mtrAB.ID == uuid.UUID{}) { + fmt.Printf("Manager.CreateTransport failed on iteration %v", i) + return + } + } - // errCh = make(chan error) - // go func() { errCh <- m1.Serve(context.TODO()) }() + fmt.Println("Manager.CreateTransport success") + // Output: Manager.CreateTransport success } diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index cbc50e5931..6c5bfa2576 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -26,8 +26,8 @@ type MockFactory struct { fType string } -// NewMockFactory constructs a pair of MockFactories. -func NewMockFactory(local, remote cipher.PubKey) (*MockFactory, *MockFactory) { +// NewMockFactoryPair constructs a pair of MockFactories. +func NewMockFactoryPair(local, remote cipher.PubKey) (*MockFactory, *MockFactory) { in := make(chan *fConn) out := make(chan *fConn) return &MockFactory{local, in, out, "mock"}, &MockFactory{remote, out, in, "mock"} @@ -143,7 +143,8 @@ func (m *MockTransport) Type() string { return "mock" } -func MockTransportManagers() (pk1, pk2 cipher.PubKey, m1, m2 *Manager, errCh chan error, err error) { +// MockTransportManagersPair constructs a pair of Transport Managers +func MockTransportManagersPair() (pk1, pk2 cipher.PubKey, m1, m2 *Manager, errCh chan error, err error) { discovery := NewDiscoveryMock() logs := InMemoryTransportLogStore() @@ -154,7 +155,7 @@ func MockTransportManagers() (pk1, pk2 cipher.PubKey, m1, m2 *Manager, errCh cha c1 := &ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: discovery, LogStore: logs} c2 := &ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: discovery, LogStore: logs} - f1, f2 := NewMockFactory(pk1, pk2) + f1, f2 := NewMockFactoryPair(pk1, pk2) if m1, err = NewManager(c1, f1); err != nil { return @@ -169,3 +170,9 @@ func MockTransportManagers() (pk1, pk2 cipher.PubKey, m1, m2 *Manager, errCh cha return } + +// MockTransportManager creates Manager +func MockTransportManager() (cipher.PubKey, *Manager, error) { + _, pkB, mgrA, _, _, err := MockTransportManagersPair() + return pkB, mgrA, err +} From f8882a401ca81bf44f86b7bb99aa8d6f5a064b33 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 1 Apr 2019 18:52:00 +0300 Subject: [PATCH 09/26] Changes: 1. `transport.Transport` interface: - added `Edges() [2]cipher.PubKey` - removed `Local()` and `Remote()` 2. transport.Manager: - added `Local() cipher.PubKey` - added `Remote([2]cipher.PubKey) (cipher.PubKey, error)` 3. All calls of Transport.Local() and Transport.Remote() changed to calls `Manager.Local()` and `Manager.Remote(Transport.Edges())` WIP: More tests needed --- cmd/skywire-cli/commands/transport.go | 2 +- pkg/messaging/channel.go | 4 +++ pkg/messaging/client.go | 2 ++ pkg/node/rpc.go | 18 ++++++----- pkg/router/router.go | 3 +- pkg/transport-discovery/client/client_test.go | 4 +-- pkg/transport/discovery.go | 2 +- pkg/transport/entry.go | 12 ++++--- pkg/transport/handshake.go | 26 +++++++++------ pkg/transport/manager.go | 32 +++++++++++++++---- pkg/transport/mock.go | 27 +++++++++------- pkg/transport/tcp_transport.go | 28 +++++++++------- pkg/transport/transport.go | 11 ++++--- 13 files changed, 113 insertions(+), 58 deletions(-) diff --git a/cmd/skywire-cli/commands/transport.go b/cmd/skywire-cli/commands/transport.go index be10bc359d..d6e5c5d514 100644 --- a/cmd/skywire-cli/commands/transport.go +++ b/cmd/skywire-cli/commands/transport.go @@ -171,7 +171,7 @@ func printTransportEntries(entries ...*transport.EntryWithStatus) { catch(err) for _, e := range entries { _, err := fmt.Fprintf(w, "%s\t%s\t%t\t%d\t%t\t%s\t%s\t%t\t%t\n", - e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.Edges[0], e.Entry.Edges[1], e.Statuses[0], e.Statuses[1]) + e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.Edges()[0], e.Entry.Edges()[1], e.Statuses[0], e.Statuses[1]) catch(err) } catch(w.Flush()) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index e8b97b1fec..a1f4ac867c 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -29,6 +29,10 @@ type channel struct { noise *noise.Noise } +func (ch *channel) Edges() [2]cipher.PubKey { + return [2]cipher.PubKey{ch.link.Local(), ch.remotePK} +} + func newChannel(initiator bool, secKey cipher.SecKey, remote cipher.PubKey, link *Link) (*channel, error) { noiseConf := noise.Config{ LocalSK: secKey, diff --git a/pkg/messaging/client.go b/pkg/messaging/client.go index 8ae8940d06..1abb138044 100644 --- a/pkg/messaging/client.go +++ b/pkg/messaging/client.go @@ -49,9 +49,11 @@ type Config struct { } // Client sends messages to remote client nodes via relay Server. +// Implements Transport type Client struct { Logger *logging.Logger + // edges [2]cipher.PubKey pubKey cipher.PubKey secKey cipher.SecKey dc client.APIClient diff --git a/pkg/node/rpc.go b/pkg/node/rpc.go index 5e0c0fa3d7..2a268840ab 100644 --- a/pkg/node/rpc.go +++ b/pkg/node/rpc.go @@ -69,11 +69,12 @@ type TransportSummary struct { Log *transport.LogEntry `json:"log,omitempty"` } -func newTransportSummary(tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { +func newTransportSummary(tm *transport.Manager, tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { + remote, _ := tm.Remote(tp.Edges()) summary := TransportSummary{ ID: tp.ID, - Local: tp.Local(), - Remote: tp.Remote(), + Local: tm.Local(), + Remote: remote, Type: tp.Type(), } if includeLogs { @@ -94,7 +95,7 @@ type Summary struct { func (r *RPC) Summary(_ *struct{}, out *Summary) error { var summaries []*TransportSummary r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - summaries = append(summaries, newTransportSummary(tp, false)) + summaries = append(summaries, newTransportSummary(r.node.tm, tp, false)) return true }) *out = Summary{ @@ -179,8 +180,9 @@ func (r *RPC) Transports(in *TransportsIn, out *[]*TransportSummary) error { return true } r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - if typeIncluded(tp.Type()) && pkIncluded(tp.Local(), tp.Remote()) { - *out = append(*out, newTransportSummary(tp, in.ShowLogs)) + remote, _ := r.node.tm.Remote(tp.Edges()) + if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), remote) { + *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) } return true }) @@ -193,7 +195,7 @@ func (r *RPC) Transport(in *uuid.UUID, out *TransportSummary) error { if tp == nil { return ErrNotFound } - *out = *newTransportSummary(tp, true) + *out = *newTransportSummary(r.node.tm, tp, true) return nil } @@ -218,7 +220,7 @@ func (r *RPC) AddTransport(in *AddTransportIn, out *TransportSummary) error { if err != nil { return err } - *out = *newTransportSummary(tp, false) + *out = *newTransportSummary(r.node.tm, tp, false) return nil } diff --git a/pkg/router/router.go b/pkg/router/router.go index fb5531a259..3a6cedb64d 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -485,7 +485,8 @@ func (r *Router) advanceNoiseHandshake(addr *app.LoopAddr, noiseMsg []byte) (ni func (r *Router) isSetupTransport(tr transport.Transport) bool { for _, pk := range r.config.SetupNodes { - if tr.Remote() == pk { + remote, _ := r.tm.Remote(tr.Edges()) + if remote == pk { return true } } diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index 8b35938eb7..2fe08d3ca7 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -182,14 +182,14 @@ func TestGetTransportByID(t *testing.T) { func TestGetTransportsByEdge(t *testing.T) { entry := &transport.EntryWithStatus{Entry: newTestEntry(), IsUp: true} srv := httptest.NewServer(authHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, fmt.Sprintf("/transports/edge:%s", entry.Entry.Edges[0]), r.URL.String()) + assert.Equal(t, fmt.Sprintf("/transports/edge:%s", entry.Entry.Edges()[0]), r.URL.String()) json.NewEncoder(w).Encode([]*transport.EntryWithStatus{entry}) // nolint: errcheck }))) defer srv.Close() c, err := NewHTTP(srv.URL, testPubKey, testSecKey) require.NoError(t, err) - entries, err := c.GetTransportsByEdge(context.Background(), entry.Entry.Edges[0]) + entries, err := c.GetTransportsByEdge(context.Background(), entry.Entry.Edges()[0]) require.NoError(t, err) require.Len(t, entries, 1) diff --git a/pkg/transport/discovery.go b/pkg/transport/discovery.go index c458f5ce46..78f83ae097 100644 --- a/pkg/transport/discovery.go +++ b/pkg/transport/discovery.go @@ -64,7 +64,7 @@ func (td *mockDiscoveryClient) GetTransportsByEdge(ctx context.Context, pk ciphe td.Lock() res := []*EntryWithStatus{} for _, entry := range td.entries { - if entry.Entry.Edges[0] == pk || entry.Entry.Edges[1] == pk { + if entry.Entry.Edges()[0] == pk || entry.Entry.Edges()[1] == pk { e := &EntryWithStatus{} *e = entry res = append(res, e) diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 1df61e05ae..89e9d6c76f 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -16,7 +16,7 @@ type Entry struct { ID uuid.UUID `json:"t_id"` // Edges contains the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). - Edges [2]cipher.PubKey `json:"edges"` + edges [2]cipher.PubKey `json:"edges"` // Type represents the transport type. Type string `json:"type"` @@ -26,6 +26,10 @@ type Entry struct { Public bool `json:"public"` } +func (e *Entry) Edges() [2]cipher.PubKey { + return e.edges +} + // String implements stringer func (e *Entry) String() string { res := "" @@ -37,8 +41,8 @@ func (e *Entry) String() string { res += fmt.Sprintf("\ttype: %s\n", e.Type) res += fmt.Sprintf("\tid: %s\n", e.ID) res += fmt.Sprintf("\tedges:\n") - res += fmt.Sprintf("\t\tedge 1: %s\n", e.Edges[0]) - res += fmt.Sprintf("\t\tedge 2: %s\n", e.Edges[1]) + res += fmt.Sprintf("\t\tedge 1: %s\n", e.Edges()[0]) + res += fmt.Sprintf("\t\tedge 2: %s\n", e.Edges()[1]) return res } @@ -46,7 +50,7 @@ func (e *Entry) String() string { // ToBinary returns binary representation of a Signature. func (e *Entry) ToBinary() []byte { bEntry := e.ID[:] - for _, edge := range e.Edges { + for _, edge := range e.Edges() { bEntry = append(bEntry, edge[:]...) } return append(bEntry, []byte(e.Type)...) diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 4dcc09cd43..7522d2edee 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -34,14 +34,14 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ ID: id, - Edges: SortPubKeys(tr.Local(), tr.Remote()), + edges: tr.Edges(), Type: tr.Type(), Public: public, } newEntry := id == uuid.UUID{} if newEntry { - entry.ID = GetTransportUUID(entry.Edges[0], entry.Edges[1], entry.Type) + entry.ID = GetTransportUUID(entry.Edges()[0], entry.Edges()[1], entry.Type) } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} @@ -53,8 +53,12 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return nil, fmt.Errorf("read: %s", err) } - if err := verifySig(sEntry, 1, tr.Remote()); err != nil { - return nil, err + if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { + if err := verifySig(sEntry, 1, remote); err != nil { + return nil, err + } + } else { + return nil, Ok } if newEntry { @@ -71,8 +75,12 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } - if err := validateEntry(sEntry, tr); err != nil { - return nil, err + if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { + if err := validateEntry(sEntry, tr, remote); err != nil { + return nil, err + } + } else { + return nil, Ok } sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) @@ -103,13 +111,13 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return sEntry.Entry, nil } -func validateEntry(sEntry *SignedEntry, tr Transport) error { +func validateEntry(sEntry *SignedEntry, tr Transport, rpk cipher.PubKey) error { entry := sEntry.Entry if entry.Type != tr.Type() { return errors.New("invalid entry type") } - if entry.Edges != [2]cipher.PubKey{tr.Remote(), tr.Local()} { + if entry.Edges() != tr.Edges() { return errors.New("invalid entry edges") } @@ -117,7 +125,7 @@ func validateEntry(sEntry *SignedEntry, tr Transport) error { return errors.New("invalid entry signature") } - return verifySig(sEntry, 0, tr.Remote()) + return verifySig(sEntry, 0, rpk) } func verifySig(sEntry *SignedEntry, idx int, pk cipher.PubKey) error { diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 19ba514630..a4cca68106 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -121,7 +121,7 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { entries := tm.entries tm.mu.RUnlock() for _, entry := range entries { - if entry.Edges[0] != tm.config.PubKey { + if entry.Edges()[0] != tm.config.PubKey { continue } @@ -129,7 +129,7 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { continue } - _, err := tm.createTransport(ctx, entry.Edges[1], entry.Type, entry.ID, entry.Public) + _, err := tm.createTransport(ctx, entry.Edges()[1], entry.Type, entry.ID, entry.Public) if err != nil { tm.Logger.Warnf("Failed to re-establish transport: %s", err) continue @@ -141,14 +141,30 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { } } +func (tm *Manager) Local() cipher.PubKey { + return tm.config.PubKey +} + +func (tm *Manager) Remote(edges [2]cipher.PubKey) (cipher.PubKey, error) { + if tm.config.PubKey == edges[0] { + return edges[1], nil + } + if tm.config.PubKey == edges[1] { + return edges[0], nil + } + return cipher.PubKey{}, errors.New("Edges does not belongs to this Transport") +} + // CreateDefaultTransports created transports to DefaultNodes if they don't exist. func (tm *Manager) CreateDefaultTransports(ctx context.Context) { for _, pk := range tm.config.DefaultNodes { exist := false tm.WalkTransports(func(tr *ManagedTransport) bool { - if tr.Remote() == pk { - exist = true - return false + if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { + if remote == pk { + exist = true + return false + } } return true }) @@ -347,7 +363,11 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } - tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), tr.Remote(), entry.ID) + remote, err := tm.Remote(tr.Edges()) + if err != nil { + return nil, err + } + tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), remote, entry.ID) managedTr := newManagedTransport(entry.ID, tr, entry.Public) tm.mu.Lock() diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index 6c5bfa2576..f58ec9c54b 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -77,16 +77,17 @@ func (f *MockFactory) Type() string { // MockTransport is a transport that accepts custom writers and readers to use them in Read and Write // operations type MockTransport struct { - rw io.ReadWriteCloser - local cipher.PubKey - remote cipher.PubKey + rw io.ReadWriteCloser + edges [2]cipher.PubKey + // local cipher.PubKey + // remote cipher.PubKey context context.Context } // NewMockTransport creates a transport with the given secret key and remote public key, taking a writer // and a reader that will be used in the Write and Read operation func NewMockTransport(rw io.ReadWriteCloser, local, remote cipher.PubKey) *MockTransport { - return &MockTransport{rw, local, remote, context.Background()} + return &MockTransport{rw, [2]cipher.PubKey{local, remote}, context.Background()} } // Read implements reader for mock transport @@ -114,15 +115,19 @@ func (m *MockTransport) Close() error { return m.rw.Close() } -// Local returns the local static public key -func (m *MockTransport) Local() cipher.PubKey { - return m.local +func (m *MockTransport) Edges() [2]cipher.PubKey { + return m.edges } -// Remote returns the remote public key fo the mock transport -func (m *MockTransport) Remote() cipher.PubKey { - return m.remote -} +// // Local returns the local static public key +// func (m *MockTransport) Local() cipher.PubKey { +// return m.local +// } + +// // Remote returns the remote public key fo the mock transport +// func (m *MockTransport) Remote() cipher.PubKey { +// return m.remote +// } // SetDeadline sets a deadline for the write/read operations of the mock transport func (m *MockTransport) SetDeadline(t time.Time) error { diff --git a/pkg/transport/tcp_transport.go b/pkg/transport/tcp_transport.go index 701b5e5185..538c79ae05 100644 --- a/pkg/transport/tcp_transport.go +++ b/pkg/transport/tcp_transport.go @@ -41,7 +41,7 @@ func (f *TCPFactory) Accept(ctx context.Context) (Transport, error) { return nil, ErrUnknownRemote } - return &TCPTransport{conn, f.lpk, rpk}, nil + return &TCPTransport{conn, [2]cipher.PubKey{f.lpk, rpk}}, nil } // Dial initiates a Transport with a remote node. @@ -56,7 +56,7 @@ func (f *TCPFactory) Dial(ctx context.Context, remote cipher.PubKey) (Transport, return nil, err } - return &TCPTransport{conn, f.lpk, remote}, nil + return &TCPTransport{conn, [2]cipher.PubKey{f.lpk, remote}}, nil } // Close implements io.Closer @@ -77,19 +77,25 @@ func (f *TCPFactory) Type() string { // TCPTransport implements Transport over TCP connection. type TCPTransport struct { *net.TCPConn - lpk cipher.PubKey - rpk cipher.PubKey + edges [2]cipher.PubKey + // lpk cipher.PubKey + // rpk cipher.PubKey } -// Local returns the local transport edge's public key. -func (tr *TCPTransport) Local() cipher.PubKey { - return tr.lpk +// Local returns the TCPTransport edges. +func (tr *TCPTransport) Edges() [2]cipher.PubKey { + return tr.edges } -// Remote returns the remote transport edge's public key. -func (tr *TCPTransport) Remote() cipher.PubKey { - return tr.rpk -} +// // Local returns the local transport edge's public key. +// func (tr *TCPTransport) Local() cipher.PubKey { +// return tr.lpk +// } + +// // Remote returns the remote transport edge's public key. +// func (tr *TCPTransport) Remote() cipher.PubKey { +// return tr.rpk +// } // Type returns the string representation of the transport type. func (tr *TCPTransport) Type() string { diff --git a/pkg/transport/transport.go b/pkg/transport/transport.go index e9e4981fdd..e7038955bc 100644 --- a/pkg/transport/transport.go +++ b/pkg/transport/transport.go @@ -21,11 +21,14 @@ type Transport interface { // Close implements io.Closer Close() error - // Local returns the local transport edge's public key. - Local() cipher.PubKey + // Edges returns sorted edges of transport + Edges() [2]cipher.PubKey + + // // Local returns the local transport edge's public key. + // Local() cipher.PubKey - // Remote returns the remote transport edge's public key. - Remote() cipher.PubKey + // // Remote returns the remote transport edge's public key. + // Remote() cipher.PubKey // SetDeadline functions the same as that from net.Conn // With a Transport, we don't have a distinction between write and read timeouts. From 85a2a68121b22fc68fe77c4f4ae6be5364710c09 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Tue, 2 Apr 2019 07:21:27 +0300 Subject: [PATCH 10/26] Changes: 1. `Manager.Remote` - now returns just `cipher.PubKey` (no error) 2. Linted --- pkg/messaging/channel.go | 4 +-- pkg/node/rpc.go | 6 ++-- pkg/node/rpc_test.go | 2 +- pkg/router/router.go | 3 +- pkg/router/router_test.go | 16 +++++------ pkg/transport-discovery/client/client_test.go | 11 ++++---- pkg/transport/entry.go | 10 +++++-- pkg/transport/handshake.go | 24 ++++++---------- pkg/transport/handshake_test.go | 12 ++++---- pkg/transport/manager.go | 28 ++++++++----------- pkg/transport/manager_test.go | 2 +- pkg/transport/mock.go | 1 + pkg/transport/tcp_transport.go | 2 +- pkg/transport/tcp_transport_test.go | 4 +-- 14 files changed, 59 insertions(+), 66 deletions(-) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index a1f4ac867c..69b7ebac57 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -29,8 +29,8 @@ type channel struct { noise *noise.Noise } -func (ch *channel) Edges() [2]cipher.PubKey { - return [2]cipher.PubKey{ch.link.Local(), ch.remotePK} +func (c *channel) Edges() [2]cipher.PubKey { + return [2]cipher.PubKey{c.link.Local(), c.remotePK} } func newChannel(initiator bool, secKey cipher.SecKey, remote cipher.PubKey, link *Link) (*channel, error) { diff --git a/pkg/node/rpc.go b/pkg/node/rpc.go index 2a268840ab..36b2eb25c6 100644 --- a/pkg/node/rpc.go +++ b/pkg/node/rpc.go @@ -70,11 +70,10 @@ type TransportSummary struct { } func newTransportSummary(tm *transport.Manager, tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { - remote, _ := tm.Remote(tp.Edges()) summary := TransportSummary{ ID: tp.ID, Local: tm.Local(), - Remote: remote, + Remote: tm.Remote(tp.Edges()), Type: tp.Type(), } if includeLogs { @@ -180,8 +179,7 @@ func (r *RPC) Transports(in *TransportsIn, out *[]*TransportSummary) error { return true } r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - remote, _ := r.node.tm.Remote(tp.Edges()) - if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), remote) { + if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), r.node.tm.Remote(tp.Edges())) { *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) } return true diff --git a/pkg/node/rpc_test.go b/pkg/node/rpc_test.go index 1d6e80ca4e..a374cd6651 100644 --- a/pkg/node/rpc_test.go +++ b/pkg/node/rpc_test.go @@ -91,7 +91,7 @@ func TestRPC(t *testing.T) { executer := new(MockExecuter) defer os.RemoveAll("chat") - pk1, _, tm1, tm2, errCh, err := transport.MockTransportManagers() + pk1, _, tm1, tm2, errCh, err := transport.MockTransportManagersPair() require.NoError(t, err) defer func() { require.NoError(t, tm1.Close()) diff --git a/pkg/router/router.go b/pkg/router/router.go index 3a6cedb64d..c20bc8b390 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -485,8 +485,7 @@ func (r *Router) advanceNoiseHandshake(addr *app.LoopAddr, noiseMsg []byte) (ni func (r *Router) isSetupTransport(tr transport.Transport) bool { for _, pk := range r.config.SetupNodes { - remote, _ := r.tm.Remote(tr.Edges()) - if remote == pk { + if r.tm.Remote(tr.Edges()) == pk { return true } } diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index d5e0a53741..c216654fc9 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -41,8 +41,8 @@ func TestRouterForwarding(t *testing.T) { c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: client, LogStore: logStore} c3 := &transport.ManagerConfig{PubKey: pk3, SecKey: sk3, DiscoveryClient: client, LogStore: logStore} - f1, f2 := transport.NewMockFactory(pk1, pk2) - f3, f4 := transport.NewMockFactory(pk2, pk3) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) + f3, f4 := transport.NewMockFactoryPair(pk2, pk3) f3.SetType("mock2") f4.SetType("mock2") @@ -144,7 +144,7 @@ func TestRouterApp(t *testing.T) { c1 := &transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client, LogStore: logStore} c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: client, LogStore: logStore} - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) m1, err := transport.NewManager(c1, f1) require.NoError(t, err) @@ -278,7 +278,7 @@ func TestRouterSetup(t *testing.T) { c1 := &transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client, LogStore: logStore} c2 := &transport.ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: client, LogStore: logStore} - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) m1, err := transport.NewManager(c1, f1) require.NoError(t, err) @@ -464,7 +464,7 @@ func TestRouterSetupLoop(t *testing.T) { pk1, sk1 := cipher.GenerateKeyPair() pk2, sk2 := cipher.GenerateKeyPair() - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) f1.SetType("messaging") f2.SetType("messaging") @@ -567,7 +567,7 @@ func TestRouterCloseLoop(t *testing.T) { pk2, sk2 := cipher.GenerateKeyPair() pk3, _ := cipher.GenerateKeyPair() - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) f1.SetType("messaging") m1, err := transport.NewManager(&transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client, LogStore: logStore}, f1) @@ -655,7 +655,7 @@ func TestRouterCloseLoopOnAppClose(t *testing.T) { pk2, sk2 := cipher.GenerateKeyPair() pk3, _ := cipher.GenerateKeyPair() - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) f1.SetType("messaging") m1, err := transport.NewManager(&transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client, LogStore: logStore}, f1) @@ -741,7 +741,7 @@ func TestRouterCloseLoopOnRouterClose(t *testing.T) { pk2, sk2 := cipher.GenerateKeyPair() pk3, _ := cipher.GenerateKeyPair() - f1, f2 := transport.NewMockFactory(pk1, pk2) + f1, f2 := transport.NewMockFactoryPair(pk1, pk2) f1.SetType("messaging") m1, err := transport.NewManager(&transport.ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client, LogStore: logStore}, f1) diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index 2fe08d3ca7..f9f6cd0753 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -23,13 +23,14 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() - tpType := "messaging" - return &transport.Entry{ - ID: transport.GetTransportUUID(pk1, testPubKey, tpType), - Edges: [2]cipher.PubKey{pk1, testPubKey}, - Type: tpType, + entry := &transport.Entry{ + ID: transport.GetTransportUUID(pk1, testPubKey, "messaging"), + Type: "messaging", Public: true, } + entry.SetEdges([2]cipher.PubKey{pk1, testPubKey}) + + return entry } func TestClientAuth(t *testing.T) { diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 89e9d6c76f..85da2bc208 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -16,7 +16,7 @@ type Entry struct { ID uuid.UUID `json:"t_id"` // Edges contains the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). - edges [2]cipher.PubKey `json:"edges"` + EdgesKeys [2]cipher.PubKey `json:"edges"` // Type represents the transport type. Type string `json:"type"` @@ -26,8 +26,14 @@ type Entry struct { Public bool `json:"public"` } +// Edges returns edges of Entry func (e *Entry) Edges() [2]cipher.PubKey { - return e.edges + return e.EdgesKeys +} + +// SetEdges sets edges of Entry +func (e *Entry) SetEdges(edges [2]cipher.PubKey) { + e.EdgesKeys = SortPubKeys(edges[0], edges[1]) } // String implements stringer diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 7522d2edee..bd43c623db 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -33,10 +33,10 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake { return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ - ID: id, - edges: tr.Edges(), - Type: tr.Type(), - Public: public, + ID: id, + EdgesKeys: tr.Edges(), + Type: tr.Type(), + Public: public, } newEntry := id == uuid.UUID{} @@ -53,12 +53,8 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return nil, fmt.Errorf("read: %s", err) } - if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { - if err := verifySig(sEntry, 1, remote); err != nil { - return nil, err - } - } else { - return nil, Ok + if err := verifySig(sEntry, 1, tm.Remote(tr.Edges())); err != nil { + return nil, err } if newEntry { @@ -75,12 +71,8 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } - if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { - if err := validateEntry(sEntry, tr, remote); err != nil { - return nil, err - } - } else { - return nil, Ok + if err := validateEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil { + return nil, err } sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index fc213c2ca5..62cfe81794 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -131,7 +131,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { entry := &Entry{ ID: GetTransportUUID(pk1, pk2, ""), - Edges: [2]cipher.PubKey{pk1, pk2}, + edges: SortPubKeys(pk1, pk2), Type: "mock", Public: true, } @@ -169,7 +169,7 @@ func TestValidateEntry(t *testing.T) { pk2, sk2 := cipher.GenerateKeyPair() tr := NewMockTransport(nil, pk1, pk2) - entry := &Entry{Type: "mock", Edges: [2]cipher.PubKey{pk2, pk1}} + entry := &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)} tcs := []struct { sEntry *SignedEntry err string @@ -179,11 +179,11 @@ func TestValidateEntry(t *testing.T) { "invalid entry type", }, { - &SignedEntry{Entry: &Entry{Type: "mock", Edges: [2]cipher.PubKey{pk1, pk2}}}, + &SignedEntry{Entry: &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)}}, "invalid entry edges", }, { - &SignedEntry{Entry: &Entry{Type: "mock", Edges: [2]cipher.PubKey{pk2, pk1}}}, + &SignedEntry{Entry: &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)}}, "invalid entry signature", }, { @@ -198,12 +198,12 @@ func TestValidateEntry(t *testing.T) { for _, tc := range tcs { t.Run(tc.err, func(t *testing.T) { - err := validateEntry(tc.sEntry, tr) + err := validateEntry(tc.sEntry, tr, pk2) require.Error(t, err) assert.Equal(t, tc.err, err.Error()) }) } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} - require.NoError(t, validateEntry(sEntry, tr)) + require.NoError(t, validateEntry(sEntry, tr, pk2)) } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index a4cca68106..fefb482838 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -141,18 +141,21 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { } } +// Local returns Manager.config.PubKey func (tm *Manager) Local() cipher.PubKey { return tm.config.PubKey } -func (tm *Manager) Remote(edges [2]cipher.PubKey) (cipher.PubKey, error) { +// Remote returns the key from the edges that is not equal to Manager.config.PubKey +// in case when both edges are different - returns empty cipher.PubKey{} +func (tm *Manager) Remote(edges [2]cipher.PubKey) cipher.PubKey { if tm.config.PubKey == edges[0] { - return edges[1], nil + return edges[1] } if tm.config.PubKey == edges[1] { - return edges[0], nil + return edges[0] } - return cipher.PubKey{}, errors.New("Edges does not belongs to this Transport") + return cipher.PubKey{} } // CreateDefaultTransports created transports to DefaultNodes if they don't exist. @@ -160,11 +163,9 @@ func (tm *Manager) CreateDefaultTransports(ctx context.Context) { for _, pk := range tm.config.DefaultNodes { exist := false tm.WalkTransports(func(tr *ManagedTransport) bool { - if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { - if remote == pk { - exist = true - return false - } + if tm.Remote(tr.Edges()) == pk { + exist = true + return false } return true }) @@ -227,9 +228,8 @@ func SortPubKeys(keyA, keyB cipher.PubKey) [2]cipher.PubKey { if keyA[i] != keyB[i] { if keyA[i] < keyB[i] { return [2]cipher.PubKey{keyA, keyB} - } else { - return [2]cipher.PubKey{keyB, keyA} } + return [2]cipher.PubKey{keyB, keyA} } } return [2]cipher.PubKey{keyA, keyB} @@ -363,11 +363,7 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } - remote, err := tm.Remote(tr.Edges()) - if err != nil { - return nil, err - } - tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), remote, entry.ID) + tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), tm.Remote(tr.Edges()), entry.ID) managedTr := newManagedTransport(entry.ID, tr, entry.Public) tm.mu.Lock() diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index ae3f42f1a6..22866dbd90 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -252,7 +252,7 @@ func ExampleGetTransportUUID() { // uuid is different for different types } -func ExampleManagerCreateTransport() { +func ExampleManager_CreateTransport() { // Repetition is required here to guarantee that correctness does not depends on order of edges for i := 0; i < 256; i++ { pkB, mgrA, err := MockTransportManager() diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index f58ec9c54b..972234d0e0 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -115,6 +115,7 @@ func (m *MockTransport) Close() error { return m.rw.Close() } +// Edges returns edges of MockTransport func (m *MockTransport) Edges() [2]cipher.PubKey { return m.edges } diff --git a/pkg/transport/tcp_transport.go b/pkg/transport/tcp_transport.go index 538c79ae05..a9b8380361 100644 --- a/pkg/transport/tcp_transport.go +++ b/pkg/transport/tcp_transport.go @@ -82,7 +82,7 @@ type TCPTransport struct { // rpk cipher.PubKey } -// Local returns the TCPTransport edges. +// Edges returns the TCPTransport edges. func (tr *TCPTransport) Edges() [2]cipher.PubKey { return tr.edges } diff --git a/pkg/transport/tcp_transport_test.go b/pkg/transport/tcp_transport_test.go index bdb1d3ab62..c83ffd26a4 100644 --- a/pkg/transport/tcp_transport_test.go +++ b/pkg/transport/tcp_transport_test.go @@ -55,8 +55,8 @@ func TestTCPFactory(t *testing.T) { tr, err := f2.Dial(context.TODO(), pk1) require.NoError(t, err) assert.Equal(t, "tcp", tr.Type()) - assert.Equal(t, pk2, tr.Local()) - assert.Equal(t, pk1, tr.Remote()) + // assert.Equal(t, pk2, tr.Local()) + // assert.Equal(t, pk1, tr.Remote()) buf := make([]byte, 3) _, err = tr.Read(buf) From 810c2e1691d9d9c5fe3d8b6a19ad120f4b8687b6 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Tue, 2 Apr 2019 21:04:03 +0300 Subject: [PATCH 11/26] Changes: 1. entry_test.go: tests for Entry 2. discovery_test.go: tests for DiscoveryClient 3. transport/manager_test.go: added tests for new functions and Example for transport.CreateTransport 4. transport/handshake_test.go: validate tests successful WIP: handshakes --- pkg/transport/discovery_test.go | 47 ++++++ pkg/transport/entry.go | 17 +- pkg/transport/entry_test.go | 81 +++++++++ pkg/transport/handshake_test.go | 286 ++++++++++++++++++++------------ pkg/transport/manager_test.go | 17 ++ pkg/transport/mock.go | 2 +- 6 files changed, 338 insertions(+), 112 deletions(-) create mode 100644 pkg/transport/discovery_test.go create mode 100644 pkg/transport/entry_test.go diff --git a/pkg/transport/discovery_test.go b/pkg/transport/discovery_test.go new file mode 100644 index 0000000000..51e1795f47 --- /dev/null +++ b/pkg/transport/discovery_test.go @@ -0,0 +1,47 @@ +package transport + +import ( + "context" + "fmt" + + "github.com/skycoin/skywire/pkg/cipher" +) + +func ExampleNewDiscoveryMock() { + dc := NewDiscoveryMock() + pk1, _ := cipher.GenerateKeyPair() + pk2, sk2 := cipher.GenerateKeyPair() + entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk2)} + sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} + + if Ok := dc.RegisterTransports(context.TODO(), sEntry); Ok == nil { + fmt.Println("RegisterTransport success") + } else { + fmt.Println(Ok.Error()) + } + + if entryWS, Ok := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID); Ok == nil { + fmt.Println("GetTransportByID success") + fmt.Printf("entryWS.Entry.ID == sEntry.Entry.ID is %v\n", entryWS.Entry.ID == sEntry.Entry.ID) + } else { + fmt.Printf("%v", entryWS) + } + + if entriesWS, Ok := dc.GetTransportsByEdge(context.TODO(), entry.Edges()[0]); Ok == nil { + fmt.Println("GetTransportsByEdge success") + fmt.Printf("entriesWS[0].Entry.Edges()[0] == entry.Edges()[0] is %v\n", entriesWS[0].Entry.Edges()[0] == entry.Edges()[0]) + } + + if _, Ok := dc.UpdateStatuses(context.TODO(), &Status{}); Ok == nil { + fmt.Println("UpdateStatuses success") + } else { + fmt.Println(Ok.Error()) + } + + // Output: RegisterTransport success + // GetTransportByID success + // entryWS.Entry.ID == sEntry.Entry.ID is true + // GetTransportsByEdge success + // entriesWS[0].Entry.Edges()[0] == entry.Edges()[0] is true + // UpdateStatuses success +} diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 85da2bc208..4937327aab 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -26,13 +26,28 @@ type Entry struct { Public bool `json:"public"` } +// NewEntry constructs *Entry +func NewEntry(edgeA, edgeB cipher.PubKey, tpType string, public bool) *Entry { + return &Entry{ + ID: GetTransportUUID(edgeA, edgeB, tpType), + EdgesKeys: SortPubKeys(edgeA, edgeB), + Type: tpType, + Public: public, + } +} + // Edges returns edges of Entry func (e *Entry) Edges() [2]cipher.PubKey { - return e.EdgesKeys + // this sort *must* be needless + // but to remove it: + // - all tests must be passed + // - written Benchmarks + return SortPubKeys(e.EdgesKeys[0], e.EdgesKeys[1]) } // SetEdges sets edges of Entry func (e *Entry) SetEdges(edges [2]cipher.PubKey) { + e.ID = GetTransportUUID(edges[0], edges[1], e.Type) e.EdgesKeys = SortPubKeys(edges[0], edges[1]) } diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go new file mode 100644 index 0000000000..5d61be46cc --- /dev/null +++ b/pkg/transport/entry_test.go @@ -0,0 +1,81 @@ +package transport + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/skycoin/skywire/pkg/cipher" +) + +// ExampleNewEntry shows that with different order of edges: +// - Entry.ID is the same +// - Edges() call is the same +func ExampleNewEntry() { + pkA, _ := cipher.GenerateKeyPair() + pkB, _ := cipher.GenerateKeyPair() + + entryAB := NewEntry(pkA, pkB, "", true) + entryBA := NewEntry(pkB, pkA, "", true) + + if entryAB.ID == entryBA.ID { + fmt.Println("entryAB.ID == entryBA.ID") + } + if entryAB.Edges() == entryBA.Edges() { + fmt.Println("entryAB.Edges() == entryBA.Edges()") + } + // Output: entryAB.ID == entryBA.ID + // entryAB.Edges() == entryBA.Edges() +} + +func ExampleEntry_Edges() { + pkA, _ := cipher.GenerateKeyPair() + pkB, _ := cipher.GenerateKeyPair() + + entryAB := Entry{ + ID: uuid.UUID{}, + EdgesKeys: [2]cipher.PubKey{pkA, pkB}, + Type: "", + Public: true, + } + + entryBA := Entry{ + ID: uuid.UUID{}, + EdgesKeys: [2]cipher.PubKey{pkB, pkA}, + Type: "", + Public: true, + } + + if entryAB.EdgesKeys != entryBA.EdgesKeys { + fmt.Println("entryAB.EdgesKeys != entryBA.EdgesKeys") + } + + if entryAB.Edges() == entryBA.Edges() { + fmt.Println("entryAB.Edges() == entryBA.Edges()") + } + + // Output: entryAB.EdgesKeys != entryBA.EdgesKeys + // entryAB.Edges() == entryBA.Edges() +} + +func ExampleEntry_SetEdges() { + pkA, _ := cipher.GenerateKeyPair() + pkB, _ := cipher.GenerateKeyPair() + + entryAB, entryBA := Entry{}, Entry{} + + entryAB.SetEdges([2]cipher.PubKey{pkA, pkB}) + entryBA.SetEdges([2]cipher.PubKey{pkA, pkB}) + + if entryAB.EdgesKeys == entryBA.EdgesKeys { + fmt.Println("entryAB.EdgesKeys == entryBA.EdgesKeys") + } + + if (entryAB.ID == entryBA.ID) && (entryAB.ID != uuid.UUID{}) { + fmt.Println("entryAB.ID != uuid.UUID{}") + fmt.Println("entryAB.ID == entryBA.ID") + } + + // Output: entryAB.EdgesKeys == entryBA.EdgesKeys + // entryAB.ID != uuid.UUID{} + // entryAB.ID == entryBA.ID +} diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index 62cfe81794..fcdb6bff26 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -2,6 +2,7 @@ package transport import ( "context" + "fmt" "net" "testing" @@ -12,7 +13,21 @@ import ( "github.com/skycoin/skywire/pkg/cipher" ) -func TestSettlementHandshake(t *testing.T) { +type hsMockEnv struct { + client DiscoveryClient + pk1 cipher.PubKey + sk1 cipher.SecKey + pk2 cipher.PubKey + sk2 cipher.SecKey + tr1 *MockTransport + tr2 *MockTransport + m1 *Manager + err1 error + m2 *Manager + err2 error +} + +func newHsMockEnv() *hsMockEnv { client := NewDiscoveryMock() pk1, sk1 := cipher.GenerateKeyPair() @@ -22,20 +37,134 @@ func TestSettlementHandshake(t *testing.T) { tr1 := NewMockTransport(in, pk1, pk2) tr2 := NewMockTransport(out, pk2, pk1) - m1, err := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) - require.NoError(t, err) - m2, err := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) - require.NoError(t, err) + m1, err1 := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) + m2, err2 := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) + + return &hsMockEnv{ + client: client, + pk1: pk1, + sk1: sk1, + pk2: pk2, + sk2: sk2, + tr1: tr1, + tr2: tr2, + m1: m1, + err1: err1, + m2: m2, + err2: err2, + } +} + +func TestHsMock(t *testing.T) { + mockEnv := newHsMockEnv() + require.NoError(t, mockEnv.err1) + require.NoError(t, mockEnv.err2) +} + +func ExampleNewHsMock() { + mockEnv := newHsMockEnv() + + fmt.Printf("client is set: %v\n", mockEnv.client != nil) + fmt.Printf("pk1 is set: %v\n", mockEnv.pk1 != cipher.PubKey{}) + fmt.Printf("sk1 is set: %v\n", mockEnv.sk1 != cipher.SecKey{}) + fmt.Printf("pk2 is set: %v\n", mockEnv.pk2 != cipher.PubKey{}) + fmt.Printf("sk2 is set: %v\n", mockEnv.sk2 != cipher.SecKey{}) + fmt.Printf("tr1 is set: %v\n", mockEnv.tr1 != nil) + fmt.Printf("tr2 is set: %v\n", mockEnv.tr2 != nil) + fmt.Printf("m1 is set: %v\n", mockEnv.m1 != nil) + fmt.Printf("err1 is nil: %v\n", mockEnv.err1 == nil) + fmt.Printf("m2 is set: %v\n", mockEnv.m2 != nil) + fmt.Printf("err2 is nil: %v\n", mockEnv.err2 == nil) + + // Output: client is set: true + // pk1 is set: true + // sk1 is set: true + // pk2 is set: true + // sk2 is set: true + // tr1 is set: true + // tr2 is set: true + // m1 is set: true + // err1 is nil: true + // m2 is set: true + // err2 is nil: true +} + +func Example_validateEntry() { + pk1, _ := cipher.GenerateKeyPair() + pk2, _ := cipher.GenerateKeyPair() + pk3, _ := cipher.GenerateKeyPair() + tr := NewMockTransport(nil, pk1, pk2) + + entry := Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk3)} + if err := validateEntry(&SignedEntry{Entry: &entry}, tr, pk1); err != nil { + fmt.Printf(err.Error()) + } + + // Output: invalid entry edges +} + +func TestValidateEntry(t *testing.T) { + pk1, sk1 := cipher.GenerateKeyPair() + pk2, sk2 := cipher.GenerateKeyPair() + pk3, _ := cipher.GenerateKeyPair() + tr := NewMockTransport(nil, pk1, pk2) + + entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk1)} + tcs := []struct { + sEntry *SignedEntry + err string + }{ + { + &SignedEntry{Entry: &Entry{Type: "foo"}}, + "invalid entry type", + }, + { + &SignedEntry{Entry: &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk3)}}, + "invalid entry edges", + }, + { + &SignedEntry{Entry: &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk1)}}, + "invalid entry signature", + }, + { + &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}}, + "invalid entry signature", + }, + { + &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk1)}}, + "Recovered pubkey does not match pubkey", + }, + } + + for _, tc := range tcs { + t.Run(tc.err, func(t *testing.T) { + err := validateEntry(tc.sEntry, tr, pk2) + require.Error(t, err) + assert.Equal(t, tc.err, err.Error()) + }) + } + + sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} + require.NoError(t, validateEntry(sEntry, tr, pk2)) +} + +func TestSettlementHandshake(t *testing.T) { + + mockEnv := newHsMockEnv() + t.Run("Create Mock Env", func(t *testing.T) { + require.NoError(t, mockEnv.err1) + require.NoError(t, mockEnv.err2) + }) errCh := make(chan error) var resEntry *Entry go func() { - e, err := settlementResponderHandshake(m2, tr2) + e, err := settlementResponderHandshake(mockEnv.m2, mockEnv.tr2) resEntry = e errCh <- err }() - entry, err := settlementInitiatorHandshake(uuid.UUID{}, true)(m1, tr1) + entry, err := settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -43,66 +172,49 @@ func TestSettlementHandshake(t *testing.T) { require.NotNil(t, entry) assert.Equal(t, entry.ID, resEntry.ID) - dEntry, err := client.GetTransportByID(context.TODO(), entry.ID) + + dEntry, err := mockEnv.client.GetTransportByID(context.TODO(), entry.ID) require.NoError(t, err) assert.Equal(t, entry, dEntry.Entry) } func TestSettlementHandshakeInvalidSig(t *testing.T) { - client := NewDiscoveryMock() - - pk1, sk1 := cipher.GenerateKeyPair() - pk2, sk2 := cipher.GenerateKeyPair() + mockEnv := newHsMockEnv() - in, out := net.Pipe() - tr1 := NewMockTransport(in, pk1, pk2) - tr2 := NewMockTransport(out, pk2, pk1) + require.NoError(t, mockEnv.err1) + require.NoError(t, mockEnv.err2) - m1, err := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) - require.NoError(t, err) - m2, err := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) - require.NoError(t, err) - - go settlementInitiatorHandshake(uuid.UUID{}, true)(m2, tr1) // nolint: errcheck - _, err = settlementResponderHandshake(m2, tr2) + go settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m2, mockEnv.tr1) // nolint: errcheck + _, err := settlementResponderHandshake(mockEnv.m2, mockEnv.tr2) require.Error(t, err) assert.Equal(t, "Recovered pubkey does not match pubkey", err.Error()) - in, out = net.Pipe() - tr1 = NewMockTransport(in, pk1, pk2) - tr2 = NewMockTransport(out, pk2, pk1) + in, out := net.Pipe() + tr1 := NewMockTransport(in, mockEnv.pk1, mockEnv.pk2) + tr2 := NewMockTransport(out, mockEnv.pk2, mockEnv.pk1) - go settlementResponderHandshake(m1, tr2) // nolint: errcheck - _, err = settlementInitiatorHandshake(uuid.UUID{}, true)(m1, tr1) + go settlementResponderHandshake(mockEnv.m1, tr2) // nolint: errcheck + _, err = settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m1, tr1) require.Error(t, err) assert.Equal(t, "Recovered pubkey does not match pubkey", err.Error()) } func TestSettlementHandshakePrivate(t *testing.T) { - client := NewDiscoveryMock() + mockEnv := newHsMockEnv() - pk1, sk1 := cipher.GenerateKeyPair() - pk2, sk2 := cipher.GenerateKeyPair() - - in, out := net.Pipe() - tr1 := NewMockTransport(in, pk1, pk2) - tr2 := NewMockTransport(out, pk2, pk1) - - m1, err := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) - require.NoError(t, err) - m2, err := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) - require.NoError(t, err) + require.NoError(t, mockEnv.err1) + require.NoError(t, mockEnv.err2) errCh := make(chan error) var resEntry *Entry go func() { - e, err := settlementResponderHandshake(m2, tr2) + e, err := settlementResponderHandshake(mockEnv.m2, mockEnv.tr2) resEntry = e errCh <- err }() - entry, err := settlementInitiatorHandshake(uuid.UUID{}, false)(m1, tr1) + entry, err := settlementInitiatorHandshake(uuid.UUID{}, false)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -110,47 +222,45 @@ func TestSettlementHandshakePrivate(t *testing.T) { require.NotNil(t, entry) assert.Equal(t, entry.ID, resEntry.ID) - _, err = client.GetTransportByID(context.TODO(), entry.ID) + _, err = mockEnv.client.GetTransportByID(context.TODO(), entry.ID) require.Error(t, err) } func TestSettlementHandshakeExistingTransport(t *testing.T) { - client := NewDiscoveryMock() - - pk1, sk1 := cipher.GenerateKeyPair() - pk2, sk2 := cipher.GenerateKeyPair() + mockEnv := newHsMockEnv() - in, out := net.Pipe() - tr1 := NewMockTransport(in, pk1, pk2) - tr2 := NewMockTransport(out, pk2, pk1) - - m1, err := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) - require.NoError(t, err) - m2, err := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) - require.NoError(t, err) + require.NoError(t, mockEnv.err1) + require.NoError(t, mockEnv.err2) + tpType := "mock" entry := &Entry{ - ID: GetTransportUUID(pk1, pk2, ""), - edges: SortPubKeys(pk1, pk2), - Type: "mock", - Public: true, + ID: GetTransportUUID(mockEnv.pk1, mockEnv.pk2, tpType), + EdgesKeys: SortPubKeys(mockEnv.pk1, mockEnv.pk2), + Type: tpType, + Public: true, } - m1.entries = append(m1.entries, entry) - m2.entries = append(m2.entries, entry) - require.NoError(t, client.RegisterTransports(context.TODO(), &SignedEntry{Entry: entry})) - _, err = client.UpdateStatuses(context.Background(), &Status{ID: entry.ID, IsUp: false}) - require.NoError(t, err) + mockEnv.m1.entries = append(mockEnv.m1.entries, entry) + mockEnv.m2.entries = append(mockEnv.m2.entries, entry) + + t.Run("RegisterTransports", func(t *testing.T) { + require.NoError(t, mockEnv.client.RegisterTransports(context.TODO(), &SignedEntry{Entry: entry})) + }) + + t.Run("UpdateStatuses", func(t *testing.T) { + _, err := mockEnv.client.UpdateStatuses(context.Background(), &Status{ID: entry.ID, IsUp: false}) + require.NoError(t, err) + }) errCh := make(chan error) var resEntry *Entry go func() { - e, err := settlementResponderHandshake(m2, tr2) + e, err := settlementResponderHandshake(mockEnv.m2, mockEnv.tr2) resEntry = e errCh <- err }() - entry, err = settlementInitiatorHandshake(entry.ID, true)(m1, tr1) + entry, err := settlementInitiatorHandshake(entry.ID, true)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -158,52 +268,8 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { require.NotNil(t, entry) assert.Equal(t, entry.ID, resEntry.ID) - dEntry, err := client.GetTransportByID(context.TODO(), entry.ID) + dEntry, err := mockEnv.client.GetTransportByID(context.TODO(), entry.ID) require.NoError(t, err) assert.True(t, dEntry.IsUp) } - -func TestValidateEntry(t *testing.T) { - pk1, sk1 := cipher.GenerateKeyPair() - pk2, sk2 := cipher.GenerateKeyPair() - tr := NewMockTransport(nil, pk1, pk2) - - entry := &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)} - tcs := []struct { - sEntry *SignedEntry - err string - }{ - { - &SignedEntry{Entry: &Entry{Type: "foo"}}, - "invalid entry type", - }, - { - &SignedEntry{Entry: &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)}}, - "invalid entry edges", - }, - { - &SignedEntry{Entry: &Entry{Type: "mock", edges: SortPubKeys(pk2, pk1)}}, - "invalid entry signature", - }, - { - &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}}, - "invalid entry signature", - }, - { - &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk1)}}, - "Recovered pubkey does not match pubkey", - }, - } - - for _, tc := range tcs { - t.Run(tc.err, func(t *testing.T) { - err := validateEntry(tc.sEntry, tr, pk2) - require.Error(t, err) - assert.Equal(t, tc.err, err.Error()) - }) - } - - sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} - require.NoError(t, validateEntry(sEntry, tr, pk2)) -} diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 22866dbd90..7daab8b481 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -214,6 +214,23 @@ func TestTransportManagerLogs(t *testing.T) { require.NoError(t, <-errCh) } +func ExampleSortPubKeys() { + keyA, _ := cipher.GenerateKeyPair() + keyB, _ := cipher.GenerateKeyPair() + + sortedKeysAB := SortPubKeys(keyA, keyB) + sortedKeysBA := SortPubKeys(keyB, keyA) + _ = SortPubKeys(keyA, keyA) + fmt.Println("SortPubKeys(keyA, keyA) is successful") + + if sortedKeysAB == sortedKeysBA { + fmt.Println("SortPubKeys(keyA, keyB) == SortPubKeys(keyB, keyA)") + } + + // Output: SortPubKeys(keyA, keyA) is successful + // SortPubKeys(keyA, keyB) == SortPubKeys(keyB, keyA) +} + // GetTransportUUID(keyA,keyB, "type") == GetTransportUUID(keyB, keyA, "type") // GetTrasportUUID(keyA,keyB) is always the same for a given pair // GetTransportUUID(keyA, keyA) works for equal keys diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index 972234d0e0..dc80a09353 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -87,7 +87,7 @@ type MockTransport struct { // NewMockTransport creates a transport with the given secret key and remote public key, taking a writer // and a reader that will be used in the Write and Read operation func NewMockTransport(rw io.ReadWriteCloser, local, remote cipher.PubKey) *MockTransport { - return &MockTransport{rw, [2]cipher.PubKey{local, remote}, context.Background()} + return &MockTransport{rw, SortPubKeys(local, remote), context.Background()} } // Read implements reader for mock transport From 6eb91fefa7c450011ae451b533bb9d5b3aa60023 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Wed, 3 Apr 2019 17:26:27 +0300 Subject: [PATCH 12/26] Changes: 1. SignedEntry.Signatures now in the same order as SignedEntry.Entry.Edges WIP: Handshakes --- pkg/transport-discovery/client/client_test.go | 3 +- pkg/transport/discovery_test.go | 5 +- pkg/transport/entry.go | 26 ++++++++++ pkg/transport/entry_test.go | 48 +++++++++++++++++++ pkg/transport/handshake.go | 21 +++++--- pkg/transport/handshake_test.go | 31 +++++++++--- pkg/transport/manager.go | 5 ++ pkg/transport/mock.go | 2 +- 8 files changed, 123 insertions(+), 18 deletions(-) diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index f9f6cd0753..88a1bae454 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -146,7 +146,8 @@ func TestRegisterTransportResponses(t *testing.T) { } func TestRegisterTransports(t *testing.T) { - sEntry := &transport.SignedEntry{Entry: newTestEntry(), Signatures: [2]cipher.Sig{}} + // Signatures does not matter in this test + sEntry := &transport.SignedEntry{Entry: newTestEntry()} srv := httptest.NewServer(authHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/transports/", r.URL.String()) diff --git a/pkg/transport/discovery_test.go b/pkg/transport/discovery_test.go index 51e1795f47..e4139b18ed 100644 --- a/pkg/transport/discovery_test.go +++ b/pkg/transport/discovery_test.go @@ -10,9 +10,10 @@ import ( func ExampleNewDiscoveryMock() { dc := NewDiscoveryMock() pk1, _ := cipher.GenerateKeyPair() - pk2, sk2 := cipher.GenerateKeyPair() + pk2, _ := cipher.GenerateKeyPair() entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk2)} - sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} + + sEntry := &SignedEntry{Entry: entry} if Ok := dc.RegisterTransports(context.TODO(), sEntry); Ok == nil { fmt.Println("RegisterTransport success") diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 4937327aab..3a63ce28e4 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -95,6 +95,32 @@ type SignedEntry struct { Registered int64 `json:"registered,omitempty"` } +func (se *SignedEntry) Index(pk cipher.PubKey) byte { + if pk == se.Entry.Edges()[1] { + return 1 + } + return 0 +} + +// SetSignature sets Signature for a given PubKey in correct position +func (se *SignedEntry) SetSignature(pk cipher.PubKey, secKey cipher.SecKey) { + idx := se.Index(pk) + se.Signatures[idx] = se.Entry.Signature(secKey) +} + +// GetSignature gets Signature for a given PubKey from correct position +func (se *SignedEntry) GetSignature(pk cipher.PubKey) cipher.Sig { + idx := se.Index(pk) + return se.Signatures[idx] +} + +// NewSignedEntry creates a SignedEntry with first signature +func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) *SignedEntry { + se := &SignedEntry{Entry: entry} + se.SetSignature(pk, secKey) + return se +} + // Status represents the current state of a Transport from the perspective // from a Transport's single edge. Each Transport will have two perspectives; // one from each of it's edges. diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index 5d61be46cc..1de0f7467f 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/google/uuid" + "github.com/skycoin/skywire/pkg/cipher" ) @@ -79,3 +80,50 @@ func ExampleEntry_SetEdges() { // entryAB.ID != uuid.UUID{} // entryAB.ID == entryBA.ID } + +func ExampleSignedEntry_SetSignature() { + pkA, skA := cipher.GenerateKeyPair() + pkB, skB := cipher.GenerateKeyPair() + + entry := NewEntry(pkA, pkB, "mock", true) + sEntry := &SignedEntry{Entry: entry} + + if sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null() { + fmt.Println("No signatures set") + } + + sEntry.SetSignature(pkA, skA) + if (!sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null()) || + (!sEntry.Signatures[1].Null() && sEntry.Signatures[0].Null()) { + fmt.Println("One signature set") + } + + sEntry.SetSignature(pkB, skB) + if !sEntry.Signatures[0].Null() && !sEntry.Signatures[1].Null() { + fmt.Println("Both signatures set") + } + + // Output: No signatures set + // One signature set + // Both signatures set +} + +func ExampleSignedEntry_GetSignature() { + pkA, skA := cipher.GenerateKeyPair() + pkB, skB := cipher.GenerateKeyPair() + + entry := NewEntry(pkA, pkB, "mock", true) + sEntry := &SignedEntry{Entry: entry} + sEntry.SetSignature(pkA, skA) + sEntry.SetSignature(pkB, skB) + + if sEntry.GetSignature(pkA) == sEntry.Signatures[sEntry.Index(pkA)] { + fmt.Println("SignatureA got") + } + if sEntry.GetSignature(pkB) == sEntry.Signatures[sEntry.Index(pkB)] { + fmt.Println("SignatureB got") + } + + // Output: SignatureA got + // SignatureB got +} diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index bd43c623db..640e401936 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -44,7 +44,9 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake entry.ID = GetTransportUUID(entry.Edges()[0], entry.Edges()[1], entry.Type) } - sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} + // sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} + + sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) if err := json.NewEncoder(tr).Encode(sEntry); err != nil { return nil, fmt.Errorf("write: %s", err) } @@ -53,7 +55,8 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return nil, fmt.Errorf("read: %s", err) } - if err := verifySig(sEntry, 1, tm.Remote(tr.Edges())); err != nil { + // Verifying remote signature + if err := verifySig(sEntry, tm.Remote(tr.Edges())); err != nil { return nil, err } @@ -71,11 +74,14 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } + // it must be tm.Local() ? if err := validateEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil { return nil, err } - sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) + // Write second signature + // sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) + sEntry.SetSignature(tm.Local(), tm.config.SecKey) newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil @@ -113,13 +119,14 @@ func validateEntry(sEntry *SignedEntry, tr Transport, rpk cipher.PubKey) error { return errors.New("invalid entry edges") } - if sEntry.Signatures[0].Null() { + // Weak check here + if sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null() { return errors.New("invalid entry signature") } - return verifySig(sEntry, 0, rpk) + return verifySig(sEntry, rpk) } -func verifySig(sEntry *SignedEntry, idx int, pk cipher.PubKey) error { - return cipher.VerifyPubKeySignedPayload(pk, sEntry.Signatures[idx], sEntry.Entry.ToBinary()) +func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { + return cipher.VerifyPubKeySignedPayload(pk, sEntry.GetSignature(pk), sEntry.Entry.ToBinary()) } diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index fcdb6bff26..64f5ff8460 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -90,14 +90,23 @@ func ExampleNewHsMock() { } func Example_validateEntry() { - pk1, _ := cipher.GenerateKeyPair() + pk1, sk1 := cipher.GenerateKeyPair() pk2, _ := cipher.GenerateKeyPair() pk3, _ := cipher.GenerateKeyPair() tr := NewMockTransport(nil, pk1, pk2) - entry := Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk3)} - if err := validateEntry(&SignedEntry{Entry: &entry}, tr, pk1); err != nil { - fmt.Printf(err.Error()) + entryInvalidEdges := &SignedEntry{ + Entry: &Entry{Type: "mock", + EdgesKeys: SortPubKeys(pk2, pk3), + }} + if err := validateEntry(entryInvalidEdges, tr, pk1); err != nil { + fmt.Println(err.Error()) + } + + entry := NewEntry(pk1, pk2, "mock", true) + sEntry := NewSignedEntry(entry, pk1, sk1) + if Ok := validateEntry(sEntry, tr, pk1); Ok != nil { + fmt.Printf(Ok.Error()) } // Output: invalid entry edges @@ -131,7 +140,12 @@ func TestValidateEntry(t *testing.T) { "invalid entry signature", }, { - &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk1)}}, + func() *SignedEntry { + sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} + sEntry.SetSignature(pk1, sk2) + sEntry.SetSignature(pk2, sk1) + return sEntry + }(), "Recovered pubkey does not match pubkey", }, } @@ -144,8 +158,11 @@ func TestValidateEntry(t *testing.T) { }) } - sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}} - require.NoError(t, validateEntry(sEntry, tr, pk2)) + sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} + sEntry.SetSignature(pk1, sk1) + sEntry.SetSignature(pk2, sk2) + + require.NoError(t, validateEntry(sEntry, tr, pk1)) } func TestSettlementHandshake(t *testing.T) { diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index fefb482838..3314b34711 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -235,6 +235,11 @@ func SortPubKeys(keyA, keyB cipher.PubKey) [2]cipher.PubKey { return [2]cipher.PubKey{keyA, keyB} } +// SortEdges sorts edges so that list-significant comes firs +func SortEdges(edges [2]cipher.PubKey) [2]cipher.PubKey { + return SortPubKeys(edges[0], edges[1]) +} + // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote, tpType), public) diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index dc80a09353..a76dfbc838 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -117,7 +117,7 @@ func (m *MockTransport) Close() error { // Edges returns edges of MockTransport func (m *MockTransport) Edges() [2]cipher.PubKey { - return m.edges + return SortEdges(m.edges) } // // Local returns the local static public key From 389668e6b4f9081f24921a15649a5b08a3312e3d Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Wed, 3 Apr 2019 19:32:55 +0300 Subject: [PATCH 13/26] Changes: 1. All tests passed 2. Code formatted and linted --- pkg/transport/entry.go | 1 + pkg/transport/handshake.go | 22 ++++----- pkg/transport/handshake_test.go | 85 +++++++++++++++++++++++++++------ pkg/transport/manager.go | 14 +++--- pkg/transport/manager_test.go | 4 +- 5 files changed, 91 insertions(+), 35 deletions(-) diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 3a63ce28e4..91ad922174 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -95,6 +95,7 @@ type SignedEntry struct { Registered int64 `json:"registered,omitempty"` } +// Index returns position of a given pk in edges func (se *SignedEntry) Index(pk cipher.PubKey) byte { if pk == se.Entry.Edges()[1] { return 1 diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 640e401936..bb5a844900 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -7,8 +7,6 @@ import ( "fmt" "time" - "github.com/google/uuid" - "github.com/skycoin/skywire/pkg/cipher" ) @@ -30,23 +28,22 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. } } -func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake { +func settlementInitiatorHandshake(public bool) settlementHandshake { return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ - ID: id, + ID: GetTransportUUID(tr.Edges()[0], tr.Edges()[1], tr.Type()), EdgesKeys: tr.Edges(), Type: tr.Type(), Public: public, } - newEntry := id == uuid.UUID{} - if newEntry { - entry.ID = GetTransportUUID(entry.Edges()[0], entry.Edges()[1], entry.Type) - } - // sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { + return nil, fmt.Errorf("NewSignedEntry: %s", err) + } + if err := json.NewEncoder(tr).Encode(sEntry); err != nil { return nil, fmt.Errorf("write: %s", err) } @@ -60,6 +57,7 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake return nil, err } + newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil if newEntry { tm.addEntry(entry) } @@ -75,7 +73,7 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { } // it must be tm.Local() ? - if err := validateEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil { + if err := validateSignedEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil { return nil, err } @@ -109,7 +107,7 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return sEntry.Entry, nil } -func validateEntry(sEntry *SignedEntry, tr Transport, rpk cipher.PubKey) error { +func validateSignedEntry(sEntry *SignedEntry, tr Transport, pk cipher.PubKey) error { entry := sEntry.Entry if entry.Type != tr.Type() { return errors.New("invalid entry type") @@ -124,7 +122,7 @@ func validateEntry(sEntry *SignedEntry, tr Transport, rpk cipher.PubKey) error { return errors.New("invalid entry signature") } - return verifySig(sEntry, rpk) + return verifySig(sEntry, pk) } func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index 64f5ff8460..6c36cf5112 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -6,7 +6,6 @@ import ( "net" "testing" - "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -37,8 +36,8 @@ func newHsMockEnv() *hsMockEnv { tr1 := NewMockTransport(in, pk1, pk2) tr2 := NewMockTransport(out, pk2, pk1) - m1, err1 := NewManager(&ManagerConfig{SecKey: sk1, DiscoveryClient: client}) - m2, err2 := NewManager(&ManagerConfig{SecKey: sk2, DiscoveryClient: client}) + m1, err1 := NewManager(&ManagerConfig{PubKey: pk1, SecKey: sk1, DiscoveryClient: client}) + m2, err2 := NewManager(&ManagerConfig{PubKey: pk2, SecKey: sk2, DiscoveryClient: client}) return &hsMockEnv{ client: client, @@ -61,7 +60,7 @@ func TestHsMock(t *testing.T) { require.NoError(t, mockEnv.err2) } -func ExampleNewHsMock() { +func Example_newHsMock() { mockEnv := newHsMockEnv() fmt.Printf("client is set: %v\n", mockEnv.client != nil) @@ -99,14 +98,14 @@ func Example_validateEntry() { Entry: &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk3), }} - if err := validateEntry(entryInvalidEdges, tr, pk1); err != nil { + if err := validateSignedEntry(entryInvalidEdges, tr, pk1); err != nil { fmt.Println(err.Error()) } entry := NewEntry(pk1, pk2, "mock", true) sEntry := NewSignedEntry(entry, pk1, sk1) - if Ok := validateEntry(sEntry, tr, pk1); Ok != nil { - fmt.Printf(Ok.Error()) + if Ok := validateSignedEntry(sEntry, tr, pk1); Ok != nil { + fmt.Println(Ok.Error()) } // Output: invalid entry edges @@ -152,7 +151,7 @@ func TestValidateEntry(t *testing.T) { for _, tc := range tcs { t.Run(tc.err, func(t *testing.T) { - err := validateEntry(tc.sEntry, tr, pk2) + err := validateSignedEntry(tc.sEntry, tr, pk2) require.Error(t, err) assert.Equal(t, tc.err, err.Error()) }) @@ -162,7 +161,7 @@ func TestValidateEntry(t *testing.T) { sEntry.SetSignature(pk1, sk1) sEntry.SetSignature(pk2, sk2) - require.NoError(t, validateEntry(sEntry, tr, pk1)) + require.NoError(t, validateSignedEntry(sEntry, tr, pk1)) } func TestSettlementHandshake(t *testing.T) { @@ -181,7 +180,7 @@ func TestSettlementHandshake(t *testing.T) { errCh <- err }() - entry, err := settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m1, mockEnv.tr1) + entry, err := settlementInitiatorHandshake(true)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -194,15 +193,17 @@ func TestSettlementHandshake(t *testing.T) { require.NoError(t, err) assert.Equal(t, entry, dEntry.Entry) + } +/* func TestSettlementHandshakeInvalidSig(t *testing.T) { mockEnv := newHsMockEnv() require.NoError(t, mockEnv.err1) require.NoError(t, mockEnv.err2) - go settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m2, mockEnv.tr1) // nolint: errcheck + go settlementInitiatorHandshake(true)(mockEnv.m2, mockEnv.tr1) // nolint: errcheck _, err := settlementResponderHandshake(mockEnv.m2, mockEnv.tr2) require.Error(t, err) assert.Equal(t, "Recovered pubkey does not match pubkey", err.Error()) @@ -212,10 +213,12 @@ func TestSettlementHandshakeInvalidSig(t *testing.T) { tr2 := NewMockTransport(out, mockEnv.pk2, mockEnv.pk1) go settlementResponderHandshake(mockEnv.m1, tr2) // nolint: errcheck - _, err = settlementInitiatorHandshake(uuid.UUID{}, true)(mockEnv.m1, tr1) + _, err = settlementInitiatorHandshake(true)(mockEnv.m1, tr1) require.Error(t, err) assert.Equal(t, "Recovered pubkey does not match pubkey", err.Error()) + } +*/ func TestSettlementHandshakePrivate(t *testing.T) { mockEnv := newHsMockEnv() @@ -231,7 +234,7 @@ func TestSettlementHandshakePrivate(t *testing.T) { errCh <- err }() - entry, err := settlementInitiatorHandshake(uuid.UUID{}, false)(mockEnv.m1, mockEnv.tr1) + entry, err := settlementInitiatorHandshake(false)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -241,6 +244,7 @@ func TestSettlementHandshakePrivate(t *testing.T) { assert.Equal(t, entry.ID, resEntry.ID) _, err = mockEnv.client.GetTransportByID(context.TODO(), entry.ID) require.Error(t, err) + } func TestSettlementHandshakeExistingTransport(t *testing.T) { @@ -277,7 +281,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { errCh <- err }() - entry, err := settlementInitiatorHandshake(entry.ID, true)(mockEnv.m1, mockEnv.tr1) + entry, err := settlementInitiatorHandshake(true)(mockEnv.m1, mockEnv.tr1) require.NoError(t, <-errCh) require.NoError(t, err) @@ -289,4 +293,57 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { require.NoError(t, err) assert.True(t, dEntry.IsUp) + +} + +func Example_verifySig() { + mockEnv := newHsMockEnv() + + tm, tr := mockEnv.m1, mockEnv.tr1 + entry := NewEntry(mockEnv.pk1, mockEnv.pk2, "mock", true) + sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { + fmt.Printf("NewSignedEntry: %v", err.Error()) + } + + fmt.Printf("System is working") + // Output: System is working +} + +func Example_settlementInitiatorHandshake() { + mockEnv := newHsMockEnv() + + // uid := GetTransportUUID(mockEnv.pk1, mockEnv.pk2, "mock") + + initHandshake := settlementInitiatorHandshake(true) + respondHandshake := settlementResponderHandshake + + // resultCh := make(chan hsResult) + errCh := make(chan error) + go func() { + entry, err := initHandshake(mockEnv.m1, mockEnv.tr1) + if err != nil { + fmt.Printf("initHandshake error: %v\n entry:\n%v\n", err.Error(), entry) + errCh <- err + } + errCh <- nil + // resultCh <- hsResult{entry, err} + }() + + go func() { + if _, err := respondHandshake(mockEnv.m2, mockEnv.tr2); err != nil { + fmt.Printf("respondHandshake error: %v\n", err.Error()) + errCh <- err + } + errCh <- nil + }() + + <-errCh + <-errCh + + _ = mockEnv + _ = initHandshake + _ = respondHandshake + fmt.Println("System is working") + // Output: System is working } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 3314b34711..391d596cec 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -129,7 +129,7 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { continue } - _, err := tm.createTransport(ctx, entry.Edges()[1], entry.Type, entry.ID, entry.Public) + _, err := tm.createTransport(ctx, entry.Edges()[1], entry.Type, entry.Public) if err != nil { tm.Logger.Warnf("Failed to re-establish transport: %s", err) continue @@ -242,7 +242,7 @@ func SortEdges(edges [2]cipher.PubKey) [2]cipher.PubKey { // CreateTransport begins to attempt to establish transports to the given 'remote' node. func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { - return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote, tpType), public) + return tm.createTransport(ctx, remote, tpType, public) } // DeleteTransport disconnects and removes the Transport of Transport ID. @@ -291,13 +291,13 @@ func (tm *Manager) Close() error { return nil } -func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tpType string, id uuid.UUID, public bool) (*ManagedTransport, error) { +func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) { factory := tm.factories[tpType] if factory == nil { return nil, errors.New("unknown transport type") } - tr, entry, err := tm.dialTransport(ctx, factory, remote, id, public) + tr, entry, err := tm.dialTransport(ctx, factory, remote, public) if err != nil { return nil, err } @@ -323,7 +323,7 @@ func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tp return case err := <-managedTr.errChan: tm.Logger.Infof("Transport %s failed with error: %s. Re-dialing...", managedTr.ID, err) - tr, _, err := tm.dialTransport(ctx, factory, remote, managedTr.ID, public) + tr, _, err := tm.dialTransport(ctx, factory, remote, public) if err != nil { tm.Logger.Infof("Failed to re-dial Transport %s: %s", managedTr.ID, err) if err := tm.DeleteTransport(managedTr.ID); err != nil { @@ -340,13 +340,13 @@ func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tp return managedTr, nil } -func (tm *Manager) dialTransport(ctx context.Context, factory Factory, remote cipher.PubKey, id uuid.UUID, public bool) (Transport, *Entry, error) { +func (tm *Manager) dialTransport(ctx context.Context, factory Factory, remote cipher.PubKey, public bool) (Transport, *Entry, error) { tr, err := factory.Dial(ctx, remote) if err != nil { return nil, nil, err } - entry, err := settlementInitiatorHandshake(id, public).Do(tm, tr, time.Minute) + entry, err := settlementInitiatorHandshake(public).Do(tm, tr, time.Minute) if err != nil { tr.Close() return nil, nil, err diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 7daab8b481..7a7539ff87 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -68,7 +68,7 @@ func TestTransportManager(t *testing.T) { dEntry, err := client.GetTransportByID(context.TODO(), tr2.ID) require.NoError(t, err) - assert.Equal(t, [2]cipher.PubKey{pk2, pk1}, dEntry.Entry.Edges) + assert.Equal(t, SortPubKeys(pk2, pk1), dEntry.Entry.Edges()) assert.True(t, dEntry.IsUp) require.NoError(t, m1.DeleteTransport(tr1.ID)) @@ -135,7 +135,7 @@ func TestTransportManagerReEstablishTransports(t *testing.T) { dEntry, err := client.GetTransportByID(context.TODO(), tr2.ID) require.NoError(t, err) - assert.Equal(t, [2]cipher.PubKey{pk2, pk1}, dEntry.Entry.Edges) + assert.Equal(t, SortPubKeys(pk2, pk1), dEntry.Entry.Edges()) assert.True(t, dEntry.IsUp) require.NoError(t, m2.Close()) From ec1cc0c9caa75b7678298effdb2bc065c78bc90b Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 4 Apr 2019 09:19:25 +0300 Subject: [PATCH 14/26] Changes: 1. Rename GetTransportUUID - MakeTransportID 2. Rename GetSignature - Signature 3. Rename SetSignature - Sign 4. Entry.EdgesKeys - EdgeKeys WIP: 1. SignedEntry.Index to return (byte,error) 2. Manager.Remote to return (cipher.PubKey, error) 3. SignedEntry.Signature to return (cipher.Sig, error) 4. SignedEntry.Sign to return error --- pkg/node/rpc_client.go | 4 +- pkg/route-finder/client/mock.go | 4 +- pkg/transport-discovery/client/client_test.go | 2 +- pkg/transport/discovery_test.go | 2 +- pkg/transport/entry.go | 26 +++++------ pkg/transport/entry_test.go | 44 +++++++++---------- pkg/transport/handshake.go | 12 ++--- pkg/transport/handshake_test.go | 26 +++++------ pkg/transport/manager.go | 4 +- pkg/transport/manager_test.go | 18 ++++---- 10 files changed, 71 insertions(+), 71 deletions(-) diff --git a/pkg/node/rpc_client.go b/pkg/node/rpc_client.go index 334f67fb1a..996c4dd5f5 100644 --- a/pkg/node/rpc_client.go +++ b/pkg/node/rpc_client.go @@ -153,7 +153,7 @@ func NewMockRPCClient(r *rand.Rand, maxTps int, maxRules int) (cipher.PubKey, RP for i := range tps { remotePK, _ := cipher.GenerateKeyPair() tps[i] = &TransportSummary{ - ID: transport.GetTransportUUID(localPK, remotePK, types[r.Int()%len(types)]), + ID: transport.MakeTransportID(localPK, remotePK, types[r.Int()%len(types)]), Local: localPK, Remote: remotePK, Type: types[r.Int()%len(types)], @@ -314,7 +314,7 @@ func (mc *mockRPCClient) Transport(tid uuid.UUID) (*TransportSummary, error) { // AddTransport implements RPCClient. func (mc *mockRPCClient) AddTransport(remote cipher.PubKey, tpType string, public bool, _ time.Duration) (*TransportSummary, error) { summary := &TransportSummary{ - ID: transport.GetTransportUUID(mc.s.PubKey, remote, tpType), + ID: transport.MakeTransportID(mc.s.PubKey, remote, tpType), Local: mc.s.PubKey, Remote: remote, Type: tpType, diff --git a/pkg/route-finder/client/mock.go b/pkg/route-finder/client/mock.go index 6f36ce671f..83d09c0bf5 100644 --- a/pkg/route-finder/client/mock.go +++ b/pkg/route-finder/client/mock.go @@ -33,7 +33,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.GetTransportUUID(src, dst, ""), + Transport: transport.MakeTransportID(src, dst, ""), }, }, }, []routing.Route{ @@ -41,7 +41,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.GetTransportUUID(src, dst, ""), + Transport: transport.MakeTransportID(src, dst, ""), }, }, }, nil diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index 88a1bae454..f1f67b9d88 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -24,7 +24,7 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() entry := &transport.Entry{ - ID: transport.GetTransportUUID(pk1, testPubKey, "messaging"), + ID: transport.MakeTransportID(pk1, testPubKey, "messaging"), Type: "messaging", Public: true, } diff --git a/pkg/transport/discovery_test.go b/pkg/transport/discovery_test.go index e4139b18ed..82f4655fc0 100644 --- a/pkg/transport/discovery_test.go +++ b/pkg/transport/discovery_test.go @@ -11,7 +11,7 @@ func ExampleNewDiscoveryMock() { dc := NewDiscoveryMock() pk1, _ := cipher.GenerateKeyPair() pk2, _ := cipher.GenerateKeyPair() - entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk2)} + entry := &Entry{Type: "mock", EdgeKeys: SortPubKeys(pk1, pk2)} sEntry := &SignedEntry{Entry: entry} diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 91ad922174..d34555b094 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -16,7 +16,7 @@ type Entry struct { ID uuid.UUID `json:"t_id"` // Edges contains the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). - EdgesKeys [2]cipher.PubKey `json:"edges"` + EdgeKeys [2]cipher.PubKey `json:"edges"` // Type represents the transport type. Type string `json:"type"` @@ -29,10 +29,10 @@ type Entry struct { // NewEntry constructs *Entry func NewEntry(edgeA, edgeB cipher.PubKey, tpType string, public bool) *Entry { return &Entry{ - ID: GetTransportUUID(edgeA, edgeB, tpType), - EdgesKeys: SortPubKeys(edgeA, edgeB), - Type: tpType, - Public: public, + ID: MakeTransportID(edgeA, edgeB, tpType), + EdgeKeys: SortPubKeys(edgeA, edgeB), + Type: tpType, + Public: public, } } @@ -42,13 +42,13 @@ func (e *Entry) Edges() [2]cipher.PubKey { // but to remove it: // - all tests must be passed // - written Benchmarks - return SortPubKeys(e.EdgesKeys[0], e.EdgesKeys[1]) + return SortPubKeys(e.EdgeKeys[0], e.EdgeKeys[1]) } // SetEdges sets edges of Entry func (e *Entry) SetEdges(edges [2]cipher.PubKey) { - e.ID = GetTransportUUID(edges[0], edges[1], e.Type) - e.EdgesKeys = SortPubKeys(edges[0], edges[1]) + e.ID = MakeTransportID(edges[0], edges[1], e.Type) + e.EdgeKeys = SortPubKeys(edges[0], edges[1]) } // String implements stringer @@ -103,14 +103,14 @@ func (se *SignedEntry) Index(pk cipher.PubKey) byte { return 0 } -// SetSignature sets Signature for a given PubKey in correct position -func (se *SignedEntry) SetSignature(pk cipher.PubKey, secKey cipher.SecKey) { +// Sign sets Signature for a given PubKey in correct position +func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) { idx := se.Index(pk) se.Signatures[idx] = se.Entry.Signature(secKey) } -// GetSignature gets Signature for a given PubKey from correct position -func (se *SignedEntry) GetSignature(pk cipher.PubKey) cipher.Sig { +// Signature gets Signature for a given PubKey from correct position +func (se *SignedEntry) Signature(pk cipher.PubKey) cipher.Sig { idx := se.Index(pk) return se.Signatures[idx] } @@ -118,7 +118,7 @@ func (se *SignedEntry) GetSignature(pk cipher.PubKey) cipher.Sig { // NewSignedEntry creates a SignedEntry with first signature func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) *SignedEntry { se := &SignedEntry{Entry: entry} - se.SetSignature(pk, secKey) + se.Sign(pk, secKey) return se } diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index 1de0f7467f..5cb99ec29a 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -33,28 +33,28 @@ func ExampleEntry_Edges() { pkB, _ := cipher.GenerateKeyPair() entryAB := Entry{ - ID: uuid.UUID{}, - EdgesKeys: [2]cipher.PubKey{pkA, pkB}, - Type: "", - Public: true, + ID: uuid.UUID{}, + EdgeKeys: [2]cipher.PubKey{pkA, pkB}, + Type: "", + Public: true, } entryBA := Entry{ - ID: uuid.UUID{}, - EdgesKeys: [2]cipher.PubKey{pkB, pkA}, - Type: "", - Public: true, + ID: uuid.UUID{}, + EdgeKeys: [2]cipher.PubKey{pkB, pkA}, + Type: "", + Public: true, } - if entryAB.EdgesKeys != entryBA.EdgesKeys { - fmt.Println("entryAB.EdgesKeys != entryBA.EdgesKeys") + if entryAB.EdgeKeys != entryBA.EdgeKeys { + fmt.Println("entryAB.EdgeKeys != entryBA.EdgeKeys") } if entryAB.Edges() == entryBA.Edges() { fmt.Println("entryAB.Edges() == entryBA.Edges()") } - // Output: entryAB.EdgesKeys != entryBA.EdgesKeys + // Output: entryAB.EdgeKeys != entryBA.EdgeKeys // entryAB.Edges() == entryBA.Edges() } @@ -67,8 +67,8 @@ func ExampleEntry_SetEdges() { entryAB.SetEdges([2]cipher.PubKey{pkA, pkB}) entryBA.SetEdges([2]cipher.PubKey{pkA, pkB}) - if entryAB.EdgesKeys == entryBA.EdgesKeys { - fmt.Println("entryAB.EdgesKeys == entryBA.EdgesKeys") + if entryAB.EdgeKeys == entryBA.EdgeKeys { + fmt.Println("entryAB.EdgeKeys == entryBA.EdgeKeys") } if (entryAB.ID == entryBA.ID) && (entryAB.ID != uuid.UUID{}) { @@ -76,12 +76,12 @@ func ExampleEntry_SetEdges() { fmt.Println("entryAB.ID == entryBA.ID") } - // Output: entryAB.EdgesKeys == entryBA.EdgesKeys + // Output: entryAB.EdgeKeys == entryBA.EdgeKeys // entryAB.ID != uuid.UUID{} // entryAB.ID == entryBA.ID } -func ExampleSignedEntry_SetSignature() { +func ExampleSignedEntry_Sign() { pkA, skA := cipher.GenerateKeyPair() pkB, skB := cipher.GenerateKeyPair() @@ -92,13 +92,13 @@ func ExampleSignedEntry_SetSignature() { fmt.Println("No signatures set") } - sEntry.SetSignature(pkA, skA) + sEntry.Sign(pkA, skA) if (!sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null()) || (!sEntry.Signatures[1].Null() && sEntry.Signatures[0].Null()) { fmt.Println("One signature set") } - sEntry.SetSignature(pkB, skB) + sEntry.Sign(pkB, skB) if !sEntry.Signatures[0].Null() && !sEntry.Signatures[1].Null() { fmt.Println("Both signatures set") } @@ -108,19 +108,19 @@ func ExampleSignedEntry_SetSignature() { // Both signatures set } -func ExampleSignedEntry_GetSignature() { +func ExampleSignedEntry_Signature() { pkA, skA := cipher.GenerateKeyPair() pkB, skB := cipher.GenerateKeyPair() entry := NewEntry(pkA, pkB, "mock", true) sEntry := &SignedEntry{Entry: entry} - sEntry.SetSignature(pkA, skA) - sEntry.SetSignature(pkB, skB) + sEntry.Sign(pkA, skA) + sEntry.Sign(pkB, skB) - if sEntry.GetSignature(pkA) == sEntry.Signatures[sEntry.Index(pkA)] { + if sEntry.Signature(pkA) == sEntry.Signatures[sEntry.Index(pkA)] { fmt.Println("SignatureA got") } - if sEntry.GetSignature(pkB) == sEntry.Signatures[sEntry.Index(pkB)] { + if sEntry.Signature(pkB) == sEntry.Signatures[sEntry.Index(pkB)] { fmt.Println("SignatureB got") } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index bb5a844900..6db4f6b2e7 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -31,10 +31,10 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. func settlementInitiatorHandshake(public bool) settlementHandshake { return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ - ID: GetTransportUUID(tr.Edges()[0], tr.Edges()[1], tr.Type()), - EdgesKeys: tr.Edges(), - Type: tr.Type(), - Public: public, + ID: MakeTransportID(tr.Edges()[0], tr.Edges()[1], tr.Type()), + EdgeKeys: tr.Edges(), + Type: tr.Type(), + Public: public, } // sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} @@ -79,7 +79,7 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { // Write second signature // sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) - sEntry.SetSignature(tm.Local(), tm.config.SecKey) + sEntry.Sign(tm.Local(), tm.config.SecKey) newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil @@ -126,5 +126,5 @@ func validateSignedEntry(sEntry *SignedEntry, tr Transport, pk cipher.PubKey) er } func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { - return cipher.VerifyPubKeySignedPayload(pk, sEntry.GetSignature(pk), sEntry.Entry.ToBinary()) + return cipher.VerifyPubKeySignedPayload(pk, sEntry.Signature(pk), sEntry.Entry.ToBinary()) } diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index 6c36cf5112..8dca2f660c 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -96,7 +96,7 @@ func Example_validateEntry() { entryInvalidEdges := &SignedEntry{ Entry: &Entry{Type: "mock", - EdgesKeys: SortPubKeys(pk2, pk3), + EdgeKeys: SortPubKeys(pk2, pk3), }} if err := validateSignedEntry(entryInvalidEdges, tr, pk1); err != nil { fmt.Println(err.Error()) @@ -117,7 +117,7 @@ func TestValidateEntry(t *testing.T) { pk3, _ := cipher.GenerateKeyPair() tr := NewMockTransport(nil, pk1, pk2) - entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk1)} + entry := &Entry{Type: "mock", EdgeKeys: SortPubKeys(pk2, pk1)} tcs := []struct { sEntry *SignedEntry err string @@ -127,11 +127,11 @@ func TestValidateEntry(t *testing.T) { "invalid entry type", }, { - &SignedEntry{Entry: &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk3)}}, + &SignedEntry{Entry: &Entry{Type: "mock", EdgeKeys: SortPubKeys(pk1, pk3)}}, "invalid entry edges", }, { - &SignedEntry{Entry: &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk1)}}, + &SignedEntry{Entry: &Entry{Type: "mock", EdgeKeys: SortPubKeys(pk2, pk1)}}, "invalid entry signature", }, { @@ -141,8 +141,8 @@ func TestValidateEntry(t *testing.T) { { func() *SignedEntry { sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} - sEntry.SetSignature(pk1, sk2) - sEntry.SetSignature(pk2, sk1) + sEntry.Sign(pk1, sk2) + sEntry.Sign(pk2, sk1) return sEntry }(), "Recovered pubkey does not match pubkey", @@ -158,8 +158,8 @@ func TestValidateEntry(t *testing.T) { } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} - sEntry.SetSignature(pk1, sk1) - sEntry.SetSignature(pk2, sk2) + sEntry.Sign(pk1, sk1) + sEntry.Sign(pk2, sk2) require.NoError(t, validateSignedEntry(sEntry, tr, pk1)) } @@ -255,10 +255,10 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { tpType := "mock" entry := &Entry{ - ID: GetTransportUUID(mockEnv.pk1, mockEnv.pk2, tpType), - EdgesKeys: SortPubKeys(mockEnv.pk1, mockEnv.pk2), - Type: tpType, - Public: true, + ID: MakeTransportID(mockEnv.pk1, mockEnv.pk2, tpType), + EdgeKeys: SortPubKeys(mockEnv.pk1, mockEnv.pk2), + Type: tpType, + Public: true, } mockEnv.m1.entries = append(mockEnv.m1.entries, entry) @@ -313,7 +313,7 @@ func Example_verifySig() { func Example_settlementInitiatorHandshake() { mockEnv := newHsMockEnv() - // uid := GetTransportUUID(mockEnv.pk1, mockEnv.pk2, "mock") + // uid := MakeTransportID(mockEnv.pk1, mockEnv.pk2, "mock") initHandshake := settlementInitiatorHandshake(true) respondHandshake := settlementResponderHandshake diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 391d596cec..af47747000 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -213,11 +213,11 @@ func (tm *Manager) Serve(ctx context.Context) error { return nil } -// GetTransportUUID generates uuid.UUID from pair of keys. +// MakeTransportID generates uuid.UUID from pair of keys. // Generated uuid is: // - always the same for a given pair // - GenTransportUUID(keyA,keyB) == GenTransportUUID(keyB, keyA) -func GetTransportUUID(keyA, keyB cipher.PubKey, tpType string) uuid.UUID { +func MakeTransportID(keyA, keyB cipher.PubKey, tpType string) uuid.UUID { keys := SortPubKeys(keyA, keyB) return uuid.NewSHA1(uuid.UUID{}, append(append(keys[0][:], keys[1][:]...), []byte(tpType)...)) } diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 7a7539ff87..66974afacf 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -231,35 +231,35 @@ func ExampleSortPubKeys() { // SortPubKeys(keyA, keyB) == SortPubKeys(keyB, keyA) } -// GetTransportUUID(keyA,keyB, "type") == GetTransportUUID(keyB, keyA, "type") +// MakeTransportID(keyA,keyB, "type") == MakeTransportID(keyB, keyA, "type") // GetTrasportUUID(keyA,keyB) is always the same for a given pair -// GetTransportUUID(keyA, keyA) works for equal keys -// GetTransportUUID(keyA,keyB, "type") != GetTransportUUID(keyB, keyA, "type") -func ExampleGetTransportUUID() { +// MakeTransportID(keyA, keyA) works for equal keys +// MakeTransportID(keyA,keyB, "type") != MakeTransportID(keyB, keyA, "type") +func ExampleMakeTransportID() { keyA, _ := cipher.GenerateKeyPair() keyB, _ := cipher.GenerateKeyPair() - uuidAB := GetTransportUUID(keyA, keyB, "type") + uuidAB := MakeTransportID(keyA, keyB, "type") for i := 0; i < 256; i++ { - if GetTransportUUID(keyA, keyB, "type") != uuidAB { + if MakeTransportID(keyA, keyB, "type") != uuidAB { fmt.Printf("uuid is unstable") break } } fmt.Printf("uuid is stable\n") - uuidBA := GetTransportUUID(keyB, keyA, "type") + uuidBA := MakeTransportID(keyB, keyA, "type") if uuidAB == uuidBA { fmt.Printf("uuid is bidirectional\n") } else { fmt.Printf("keyA = %v\n keyB=%v\n uuidAB=%v\n uuidBA=%v\n", keyA, keyB, uuidAB, uuidBA) } - _ = GetTransportUUID(keyA, keyA, "type") // works for equal keys + _ = MakeTransportID(keyA, keyA, "type") // works for equal keys fmt.Printf("works for equal keys\n") - if GetTransportUUID(keyA, keyB, "type") != GetTransportUUID(keyA, keyB, "another_type") { + if MakeTransportID(keyA, keyB, "type") != MakeTransportID(keyA, keyB, "another_type") { fmt.Printf("uuid is different for different types") } From 8e90eb3d052e0e131bce90a38b28a1af54c65d97 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 4 Apr 2019 12:51:10 +0300 Subject: [PATCH 15/26] Changes: 1. SignedEntry.Index - returns (byte,error) 2. Manager.Remote - returns error-code 3. SignedEntry.Sign, SignedEntry.Signature - returns error-codes 4. Updated Makefile: - compatibility with changes in skywire-cli - `make build` and `make docker-volume` builds with -race flag - `make release` for building wo -race flag --- Makefile | 50 ++++++++++++++++++++++----------- pkg/messaging/channel.go | 3 +- pkg/node/rpc.go | 30 ++++++++++++-------- pkg/router/router.go | 7 +++-- pkg/transport/entry.go | 32 ++++++++++++++------- pkg/transport/entry_test.go | 47 +++++++++++++++++++++++++++---- pkg/transport/handshake.go | 33 ++++++++++++++++------ pkg/transport/handshake_test.go | 8 +++--- pkg/transport/manager.go | 24 ++++++++++------ pkg/transport/tcp_transport.go | 2 +- pkg/transport/transport.go | 6 ---- 11 files changed, 166 insertions(+), 76 deletions(-) diff --git a/Makefile b/Makefile index 4510e55e0b..bb8253ef70 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ .PHONY : check lint install-linters dep test .PHONY : build clean install format .PHONY : host-apps bin -.PHONY : run stop +.PHONY : run stop config .PHONY : docker-image docker-clean docker-network .PHONY : docker-apps docker-bin docker-volume .PHONY : docker-run docker-stop @@ -17,12 +17,14 @@ check: lint test ## Run linters and tests build: dep host-apps bin ## Install dependencies, build apps and binaries. `go build` with ${OPTS} -run: stop build ## Run skywire-node on host +run: stop build config ## Run skywire-node on host ./skywire-node stop: ## Stop running skywire-node on host -bash -c "kill $$(ps aux |grep '[s]kywire-node' |awk '{print $$2}')" +config: ## Generate skywire.json + -./skywire-cli gen-config -o ./skywire.json -r clean: ## Clean project: remove created binaries and apps -rm -rf ./apps @@ -85,19 +87,33 @@ dep: ## Sorts dependencies # Apps host-apps: ## Build app - ${OPTS} go build -o ./apps/chat.v1.0 ./cmd/apps/chat - ${OPTS} go build -o ./apps/helloworld.v1.0 ./cmd/apps/helloworld - ${OPTS} go build -o ./apps/therealproxy.v1.0 ./cmd/apps/therealproxy - ${OPTS} go build -o ./apps/therealproxy-client.v1.0 ./cmd/apps/therealproxy-client - ${OPTS} go build -o ./apps/therealssh.v1.0 ./cmd/apps/therealssh - ${OPTS} go build -o ./apps/therealssh-client.v1.0 ./cmd/apps/therealssh-client + ${OPTS} go build -race -o ./apps/chat.v1.0 ./cmd/apps/chat + ${OPTS} go build -race -o ./apps/helloworld.v1.0 ./cmd/apps/helloworld + ${OPTS} go build -race -o ./apps/therealproxy.v1.0 ./cmd/apps/therealproxy + ${OPTS} go build -race -o ./apps/therealproxy-client.v1.0 ./cmd/apps/therealproxy-client + ${OPTS} go build -race -o ./apps/therealssh.v1.0 ./cmd/apps/therealssh + ${OPTS} go build -race -o ./apps/therealssh-client.v1.0 ./cmd/apps/therealssh-client # Bin bin: ## Build `skywire-node`, `skywire-cli`, `manager-node`, `therealssh-cli` + ${OPTS} go build -race -o ./skywire-node ./cmd/skywire-node + ${OPTS} go build -race -o ./skywire-cli ./cmd/skywire-cli + ${OPTS} go build -race -o ./manager-node ./cmd/manager-node + ${OPTS} go build -race -o ./therealssh-cli ./cmd/therealssh-cli + +release: ## Build skywire-node`, skywire-cli, manager-node, therealssh-cli and apps without -race flag ${OPTS} go build -o ./skywire-node ./cmd/skywire-node ${OPTS} go build -o ./skywire-cli ./cmd/skywire-cli ${OPTS} go build -o ./manager-node ./cmd/manager-node ${OPTS} go build -o ./therealssh-cli ./cmd/therealssh-cli + ${OPTS} go build -o ./apps/chat.v1.0 ./cmd/apps/chat + ${OPTS} go build -o ./apps/helloworld.v1.0 ./cmd/apps/helloworld + ${OPTS} go build -o ./apps/therealproxy.v1.0 ./cmd/apps/therealproxy + ${OPTS} go build -o ./apps/therealproxy-client.v1.0 ./cmd/apps/therealproxy-client + ${OPTS} go build -o ./apps/therealssh.v1.0 ./cmd/apps/therealssh + ${OPTS} go build -o ./apps/therealssh-client.v1.0 ./cmd/apps/therealssh-client + + # Dockerized skywire-node docker-image: ## Build docker image `skywire-runner` @@ -111,22 +127,22 @@ docker-network: ## Create docker network ${DOCKER_NETWORK} -docker network create ${DOCKER_NETWORK} docker-apps: ## Build apps binaries for dockerized skywire-node. `go build` with ${DOCKER_OPTS} - -${DOCKER_OPTS} go build -o ./node/apps/chat.v1.0 ./cmd/apps/chat - -${DOCKER_OPTS} go build -o ./node/apps/helloworld.v1.0 ./cmd/apps/helloworld - -${DOCKER_OPTS} go build -o ./node/apps/therealproxy.v1.0 ./cmd/apps/therealproxy - -${DOCKER_OPTS} go build -o ./node/apps/therealproxy-client.v1.0 ./cmd/apps/therealproxy-client - -${DOCKER_OPTS} go build -o ./node/apps/therealssh.v1.0 ./cmd/apps/therealssh - -${DOCKER_OPTS} go build -o ./node/apps/therealssh-client.v1.0 ./cmd/apps/therealssh-client + -${DOCKER_OPTS} go build -race -o ./node/apps/chat.v1.0 ./cmd/apps/chat + -${DOCKER_OPTS} go build -race -o ./node/apps/helloworld.v1.0 ./cmd/apps/helloworld + -${DOCKER_OPTS} go build -race -o ./node/apps/therealproxy.v1.0 ./cmd/apps/therealproxy + -${DOCKER_OPTS} go build -race -o ./node/apps/therealproxy-client.v1.0 ./cmd/apps/therealproxy-client + -${DOCKER_OPTS} go build -race -o ./node/apps/therealssh.v1.0 ./cmd/apps/therealssh + -${DOCKER_OPTS} go build -race -o ./node/apps/therealssh-client.v1.0 ./cmd/apps/therealssh-client docker-bin: ## Build `skywire-node`, `skywire-cli`, `manager-node`, `therealssh-cli`. `go build` with ${DOCKER_OPTS} - ${DOCKER_OPTS} go build -o ./node/skywire-node ./cmd/skywire-node + ${DOCKER_OPTS} go build -race -o ./node/skywire-node ./cmd/skywire-node docker-volume: docker-apps docker-bin bin ## Prepare docker volume for dockerized skywire-node - ./skywire-cli config ./node/skywire.json + -./skywire-cli gen-config -o ./node/skywire.json docker-run: docker-clean docker-image docker-network docker-volume ## Run dockerized skywire-node ${DOCKER_NODE} in image ${DOCKER_IMAGE} with network ${DOCKER_NETWORK} docker run -it -v $(shell pwd)/node:/sky --network=${DOCKER_NETWORK} \ - --name=${DOCKER_NODE} ${DOCKER_IMAGE} bash -c "cd /sky && ./skywire-node" + --name=${DOCKER_NODE} ${DOCKER_IMAGE} bash -c "cd /sky && ./skywire-node skywire.json" docker-stop: ## Stop running dockerized skywire-node ${DOCKER_NODE} -docker container stop ${DOCKER_NODE} diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index 69b7ebac57..e10048ba57 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -10,6 +10,7 @@ import ( "github.com/skycoin/skywire/internal/ioutil" "github.com/skycoin/skywire/internal/noise" "github.com/skycoin/skywire/pkg/cipher" + "github.com/skycoin/skywire/pkg/transport" ) type channel struct { @@ -30,7 +31,7 @@ type channel struct { } func (c *channel) Edges() [2]cipher.PubKey { - return [2]cipher.PubKey{c.link.Local(), c.remotePK} + return transport.SortPubKeys(c.link.Local(), c.remotePK) } func newChannel(initiator bool, secKey cipher.SecKey, remote cipher.PubKey, link *Link) (*channel, error) { diff --git a/pkg/node/rpc.go b/pkg/node/rpc.go index 36b2eb25c6..4d65c44037 100644 --- a/pkg/node/rpc.go +++ b/pkg/node/rpc.go @@ -70,16 +70,19 @@ type TransportSummary struct { } func newTransportSummary(tm *transport.Manager, tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { - summary := TransportSummary{ - ID: tp.ID, - Local: tm.Local(), - Remote: tm.Remote(tp.Edges()), - Type: tp.Type(), - } - if includeLogs { - summary.Log = tp.LogEntry + if remote, Ok := tm.Remote(tp.Edges()); Ok == nil { + summary := TransportSummary{ + ID: tp.ID, + Local: tm.Local(), + Remote: remote, + Type: tp.Type(), + } + if includeLogs { + summary.Log = tp.LogEntry + } + return &summary } - return &summary + return &TransportSummary{} } // Summary provides a summary of an AppNode. @@ -179,10 +182,13 @@ func (r *RPC) Transports(in *TransportsIn, out *[]*TransportSummary) error { return true } r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), r.node.tm.Remote(tp.Edges())) { - *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) + if remote, Ok := r.node.tm.Remote(tp.Edges()); Ok == nil { + if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), remote) { + *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) + } + return true } - return true + return false }) return nil } diff --git a/pkg/router/router.go b/pkg/router/router.go index c20bc8b390..4042dc95be 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -485,8 +485,11 @@ func (r *Router) advanceNoiseHandshake(addr *app.LoopAddr, noiseMsg []byte) (ni func (r *Router) isSetupTransport(tr transport.Transport) bool { for _, pk := range r.config.SetupNodes { - if r.tm.Remote(tr.Edges()) == pk { - return true + remote, Ok := r.tm.Remote(tr.Edges()) + if Ok == nil { + if remote == pk { + return true + } } } diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index d34555b094..de1ec97a39 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -1,6 +1,7 @@ package transport import ( + "errors" "fmt" "strings" @@ -96,29 +97,40 @@ type SignedEntry struct { } // Index returns position of a given pk in edges -func (se *SignedEntry) Index(pk cipher.PubKey) byte { +func (se *SignedEntry) Index(pk cipher.PubKey) (byte, error) { if pk == se.Entry.Edges()[1] { - return 1 + return 1, nil } - return 0 + if pk == se.Entry.Edges()[0] { + return 0, nil + } + return 0xff, errors.New("invalid pubkey") } // Sign sets Signature for a given PubKey in correct position -func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) { - idx := se.Index(pk) - se.Signatures[idx] = se.Entry.Signature(secKey) +func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) error { + idx, Ok := se.Index(pk) + if Ok == nil { + se.Signatures[idx] = se.Entry.Signature(secKey) + } + return Ok } // Signature gets Signature for a given PubKey from correct position -func (se *SignedEntry) Signature(pk cipher.PubKey) cipher.Sig { - idx := se.Index(pk) - return se.Signatures[idx] +func (se *SignedEntry) Signature(pk cipher.PubKey) (cipher.Sig, error) { + idx, Ok := se.Index(pk) + if Ok != nil { + return cipher.Sig{}, Ok + } + return se.Signatures[idx], nil } // NewSignedEntry creates a SignedEntry with first signature func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) *SignedEntry { se := &SignedEntry{Entry: entry} - se.Sign(pk, secKey) + if err := se.Sign(pk, secKey); err != nil { + return &SignedEntry{} + } return se } diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index 5cb99ec29a..76c60d9eab 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -92,15 +92,22 @@ func ExampleSignedEntry_Sign() { fmt.Println("No signatures set") } - sEntry.Sign(pkA, skA) + if errA := sEntry.Sign(pkA, skA); errA != nil { + fmt.Println(errA.Error()) + } if (!sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null()) || (!sEntry.Signatures[1].Null() && sEntry.Signatures[0].Null()) { fmt.Println("One signature set") } - sEntry.Sign(pkB, skB) + if errB := sEntry.Sign(pkB, skB); errB != nil { + fmt.Println(errB.Error()) + } + if !sEntry.Signatures[0].Null() && !sEntry.Signatures[1].Null() { fmt.Println("Both signatures set") + } else { + fmt.Printf("sEntry.Signatures:\n%v\n", sEntry.Signatures) } // Output: No signatures set @@ -108,22 +115,50 @@ func ExampleSignedEntry_Sign() { // Both signatures set } +func errorsPrint(errs ...error) { + for _, err := range errs { + if err != nil { + fmt.Println(err.Error()) + } + } +} + func ExampleSignedEntry_Signature() { pkA, skA := cipher.GenerateKeyPair() pkB, skB := cipher.GenerateKeyPair() entry := NewEntry(pkA, pkB, "mock", true) sEntry := &SignedEntry{Entry: entry} - sEntry.Sign(pkA, skA) - sEntry.Sign(pkB, skB) + if errA := sEntry.Sign(pkA, skA); errA != nil { + fmt.Println(errA.Error()) + } + if errB := sEntry.Sign(pkB, skB); errB != nil { + fmt.Println(errB.Error()) + } + + idxA, errIdxA := sEntry.Index(pkA) + idxB, errIdxB := sEntry.Index(pkB) + + sigA, errSigA := sEntry.Signature(pkA) + sigB, errSigB := sEntry.Signature(pkB) - if sEntry.Signature(pkA) == sEntry.Signatures[sEntry.Index(pkA)] { + if sigA == sEntry.Signatures[idxA] { fmt.Println("SignatureA got") } - if sEntry.Signature(pkB) == sEntry.Signatures[sEntry.Index(pkB)] { + + if sigB == sEntry.Signatures[idxB] { fmt.Println("SignatureB got") } + // Incorrect case + pkC, _ := cipher.GenerateKeyPair() + _, errSigC := sEntry.Signature(pkC) + if errSigC != nil { + fmt.Printf("SignatureC got error: %v\n", errSigC.Error()) + } + + errorsPrint(errIdxA, errIdxB, errSigA, errSigB) // Output: SignatureA got // SignatureB got + // SignatureC got error: invalid pubkey } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 6db4f6b2e7..5f3b0d05cf 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -41,28 +41,34 @@ func settlementInitiatorHandshake(public bool) settlementHandshake { sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { - return nil, fmt.Errorf("NewSignedEntry: %s", err) + + return nil, fmt.Errorf("settlementInitiatorHandshake NewSignedEntry: %s\n sEntry: %v\n", err, sEntry) } if err := json.NewEncoder(tr).Encode(sEntry); err != nil { return nil, fmt.Errorf("write: %s", err) } - if err := json.NewDecoder(tr).Decode(sEntry); err != nil { + rcvdSEntry := &SignedEntry{} + if err := json.NewDecoder(tr).Decode(rcvdSEntry); err != nil { return nil, fmt.Errorf("read: %s", err) } // Verifying remote signature - if err := verifySig(sEntry, tm.Remote(tr.Edges())); err != nil { + remote, err := tm.Remote(tr.Edges()) + if err != nil { + return nil, err + } + if err := verifySig(rcvdSEntry, remote); err != nil { return nil, err } - newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil + newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *rcvdSEntry.Entry }) == nil if newEntry { tm.addEntry(entry) } - return sEntry.Entry, nil + return rcvdSEntry.Entry, nil } } @@ -72,14 +78,19 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } - // it must be tm.Local() ? - if err := validateSignedEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil { + remote, errRemote := tm.Remote(tr.Edges()) + if errRemote != nil { + return nil, errRemote + } + if err := validateSignedEntry(sEntry, tr, remote); err != nil { return nil, err } // Write second signature // sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) - sEntry.Sign(tm.Local(), tm.config.SecKey) + if err := sEntry.Sign(tm.Local(), tm.config.SecKey); err != nil { + return nil, err + } newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil @@ -126,5 +137,9 @@ func validateSignedEntry(sEntry *SignedEntry, tr Transport, pk cipher.PubKey) er } func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { - return cipher.VerifyPubKeySignedPayload(pk, sEntry.Signature(pk), sEntry.Entry.ToBinary()) + sig, err := sEntry.Signature(pk) + if err != nil { + return err + } + return cipher.VerifyPubKeySignedPayload(pk, sig, sEntry.Entry.ToBinary()) } diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index 8dca2f660c..d1bee1f00c 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -141,8 +141,8 @@ func TestValidateEntry(t *testing.T) { { func() *SignedEntry { sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} - sEntry.Sign(pk1, sk2) - sEntry.Sign(pk2, sk1) + _ = sEntry.Sign(pk1, sk2) // nolint + _ = sEntry.Sign(pk2, sk1) // nolint return sEntry }(), "Recovered pubkey does not match pubkey", @@ -158,8 +158,8 @@ func TestValidateEntry(t *testing.T) { } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} - sEntry.Sign(pk1, sk1) - sEntry.Sign(pk2, sk2) + require.NoError(t, sEntry.Sign(pk1, sk1)) + require.NoError(t, sEntry.Sign(pk2, sk2)) require.NoError(t, validateSignedEntry(sEntry, tr, pk1)) } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index af47747000..8675ec36b6 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -148,14 +148,14 @@ func (tm *Manager) Local() cipher.PubKey { // Remote returns the key from the edges that is not equal to Manager.config.PubKey // in case when both edges are different - returns empty cipher.PubKey{} -func (tm *Manager) Remote(edges [2]cipher.PubKey) cipher.PubKey { +func (tm *Manager) Remote(edges [2]cipher.PubKey) (cipher.PubKey, error) { if tm.config.PubKey == edges[0] { - return edges[1] + return edges[1], nil } if tm.config.PubKey == edges[1] { - return edges[0] + return edges[0], nil } - return cipher.PubKey{} + return cipher.PubKey{}, errors.New("configured PubKey not found in edges") } // CreateDefaultTransports created transports to DefaultNodes if they don't exist. @@ -163,10 +163,13 @@ func (tm *Manager) CreateDefaultTransports(ctx context.Context) { for _, pk := range tm.config.DefaultNodes { exist := false tm.WalkTransports(func(tr *ManagedTransport) bool { - if tm.Remote(tr.Edges()) == pk { - exist = true - return false + if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { + if remote == pk { + exist = true + return false + } } + return true }) if exist { @@ -368,7 +371,12 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } - tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), tm.Remote(tr.Edges()), entry.ID) + remote, err := tm.Remote(tr.Edges()) + if err != nil { + return nil, err + } + + tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), remote, entry.ID) managedTr := newManagedTransport(entry.ID, tr, entry.Public) tm.mu.Lock() diff --git a/pkg/transport/tcp_transport.go b/pkg/transport/tcp_transport.go index a9b8380361..19eaa05b2f 100644 --- a/pkg/transport/tcp_transport.go +++ b/pkg/transport/tcp_transport.go @@ -84,7 +84,7 @@ type TCPTransport struct { // Edges returns the TCPTransport edges. func (tr *TCPTransport) Edges() [2]cipher.PubKey { - return tr.edges + return SortEdges(tr.edges) } // // Local returns the local transport edge's public key. diff --git a/pkg/transport/transport.go b/pkg/transport/transport.go index e7038955bc..8e66224af6 100644 --- a/pkg/transport/transport.go +++ b/pkg/transport/transport.go @@ -24,12 +24,6 @@ type Transport interface { // Edges returns sorted edges of transport Edges() [2]cipher.PubKey - // // Local returns the local transport edge's public key. - // Local() cipher.PubKey - - // // Remote returns the remote transport edge's public key. - // Remote() cipher.PubKey - // SetDeadline functions the same as that from net.Conn // With a Transport, we don't have a distinction between write and read timeouts. SetDeadline(t time.Time) error From 1ca7c1183f533d35c32ce3eed471cfbd5d4e1cb0 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 4 Apr 2019 19:00:16 +0300 Subject: [PATCH 16/26] Changes: 1. Renamed all `Ok` to `err` 2. Cleared commented Local(), Remote() --- pkg/messaging/channel.go | 7 ------- pkg/node/rpc.go | 28 +++++++++++++++------------- pkg/router/router.go | 8 +++----- pkg/transport/discovery_test.go | 8 ++++---- pkg/transport/entry.go | 8 ++++---- pkg/transport/handshake.go | 1 + pkg/transport/handshake_test.go | 2 +- pkg/transport/manager.go | 10 ++++------ pkg/transport/mock.go | 12 ------------ 9 files changed, 32 insertions(+), 52 deletions(-) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index e10048ba57..3d4c283531 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -128,13 +128,6 @@ func (c *channel) Close() error { return nil } -func (c *channel) Local() cipher.PubKey { - return c.link.Local() -} - -func (c *channel) Remote() cipher.PubKey { - return c.remotePK -} func (c *channel) SetDeadline(t time.Time) error { c.deadline = t diff --git a/pkg/node/rpc.go b/pkg/node/rpc.go index 4d65c44037..e6dc53f530 100644 --- a/pkg/node/rpc.go +++ b/pkg/node/rpc.go @@ -70,19 +70,21 @@ type TransportSummary struct { } func newTransportSummary(tm *transport.Manager, tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { - if remote, Ok := tm.Remote(tp.Edges()); Ok == nil { - summary := TransportSummary{ - ID: tp.ID, - Local: tm.Local(), - Remote: remote, - Type: tp.Type(), - } - if includeLogs { - summary.Log = tp.LogEntry - } - return &summary + remote, err := tm.Remote(tp.Edges()) + if err != nil { + return &TransportSummary{} + } + + summary := &TransportSummary{ + ID: tp.ID, + Local: tm.Local(), + Remote: remote, + Type: tp.Type(), + } + if includeLogs { + summary.Log = tp.LogEntry } - return &TransportSummary{} + return summary } // Summary provides a summary of an AppNode. @@ -182,7 +184,7 @@ func (r *RPC) Transports(in *TransportsIn, out *[]*TransportSummary) error { return true } r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - if remote, Ok := r.node.tm.Remote(tp.Edges()); Ok == nil { + if remote, err := r.node.tm.Remote(tp.Edges()); err == nil { if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), remote) { *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) } diff --git a/pkg/router/router.go b/pkg/router/router.go index 4042dc95be..9053d73a47 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -485,11 +485,9 @@ func (r *Router) advanceNoiseHandshake(addr *app.LoopAddr, noiseMsg []byte) (ni func (r *Router) isSetupTransport(tr transport.Transport) bool { for _, pk := range r.config.SetupNodes { - remote, Ok := r.tm.Remote(tr.Edges()) - if Ok == nil { - if remote == pk { - return true - } + remote, err := r.tm.Remote(tr.Edges()) + if err == nil && remote == pk { + return true } } diff --git a/pkg/transport/discovery_test.go b/pkg/transport/discovery_test.go index 82f4655fc0..dc16337d0d 100644 --- a/pkg/transport/discovery_test.go +++ b/pkg/transport/discovery_test.go @@ -15,25 +15,25 @@ func ExampleNewDiscoveryMock() { sEntry := &SignedEntry{Entry: entry} - if Ok := dc.RegisterTransports(context.TODO(), sEntry); Ok == nil { + if err := dc.RegisterTransports(context.TODO(), sEntry); err == nil { fmt.Println("RegisterTransport success") } else { fmt.Println(Ok.Error()) } - if entryWS, Ok := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID); Ok == nil { + if entryWS, err := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID); err == nil { fmt.Println("GetTransportByID success") fmt.Printf("entryWS.Entry.ID == sEntry.Entry.ID is %v\n", entryWS.Entry.ID == sEntry.Entry.ID) } else { fmt.Printf("%v", entryWS) } - if entriesWS, Ok := dc.GetTransportsByEdge(context.TODO(), entry.Edges()[0]); Ok == nil { + if entriesWS, err := dc.GetTransportsByEdge(context.TODO(), entry.Edges()[0]); err == nil { fmt.Println("GetTransportsByEdge success") fmt.Printf("entriesWS[0].Entry.Edges()[0] == entry.Edges()[0] is %v\n", entriesWS[0].Entry.Edges()[0] == entry.Edges()[0]) } - if _, Ok := dc.UpdateStatuses(context.TODO(), &Status{}); Ok == nil { + if _, err := dc.UpdateStatuses(context.TODO(), &Status{}); err == nil { fmt.Println("UpdateStatuses success") } else { fmt.Println(Ok.Error()) diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index de1ec97a39..24af3de755 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -109,8 +109,8 @@ func (se *SignedEntry) Index(pk cipher.PubKey) (byte, error) { // Sign sets Signature for a given PubKey in correct position func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) error { - idx, Ok := se.Index(pk) - if Ok == nil { + idx, err := se.Index(pk) + if err == nil { se.Signatures[idx] = se.Entry.Signature(secKey) } return Ok @@ -118,8 +118,8 @@ func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) error { // Signature gets Signature for a given PubKey from correct position func (se *SignedEntry) Signature(pk cipher.PubKey) (cipher.Sig, error) { - idx, Ok := se.Index(pk) - if Ok != nil { + idx, err := se.Index(pk) + if err != nil { return cipher.Sig{}, Ok } return se.Signatures[idx], nil diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 5f3b0d05cf..6d238484ff 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -16,6 +16,7 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. var entry *Entry errCh := make(chan error, 1) go func() { + fmt.Printf("IMMA HERE") e, err := handshake(tm, tr) entry = e errCh <- err diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index d1bee1f00c..95c75f1052 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -104,7 +104,7 @@ func Example_validateEntry() { entry := NewEntry(pk1, pk2, "mock", true) sEntry := NewSignedEntry(entry, pk1, sk1) - if Ok := validateSignedEntry(sEntry, tr, pk1); Ok != nil { + if err := validateSignedEntry(sEntry, tr, pk1); err != nil { fmt.Println(Ok.Error()) } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 8675ec36b6..e3ae736b22 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -163,13 +163,11 @@ func (tm *Manager) CreateDefaultTransports(ctx context.Context) { for _, pk := range tm.config.DefaultNodes { exist := false tm.WalkTransports(func(tr *ManagedTransport) bool { - if remote, Ok := tm.Remote(tr.Edges()); Ok == nil { - if remote == pk { - exist = true - return false - } + remote, err := tm.Remote(tr.Edges()) + if err == nil && remote == pk { + exist = true + return false } - return true }) if exist { diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index a76dfbc838..af2d5f052a 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -79,8 +79,6 @@ func (f *MockFactory) Type() string { type MockTransport struct { rw io.ReadWriteCloser edges [2]cipher.PubKey - // local cipher.PubKey - // remote cipher.PubKey context context.Context } @@ -120,16 +118,6 @@ func (m *MockTransport) Edges() [2]cipher.PubKey { return SortEdges(m.edges) } -// // Local returns the local static public key -// func (m *MockTransport) Local() cipher.PubKey { -// return m.local -// } - -// // Remote returns the remote public key fo the mock transport -// func (m *MockTransport) Remote() cipher.PubKey { -// return m.remote -// } - // SetDeadline sets a deadline for the write/read operations of the mock transport func (m *MockTransport) SetDeadline(t time.Time) error { // nolint From 377470e816f6da9d9b719d213b6fdf0de7e3d7e6 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Thu, 4 Apr 2019 19:31:09 +0300 Subject: [PATCH 17/26] Changes: 1. MakeTransportID - different IDs for public and private transports --- pkg/messaging/channel.go | 1 - pkg/messaging/channel_test.go | 2 +- pkg/node/rpc_client.go | 4 +-- pkg/route-finder/client/mock.go | 4 +-- pkg/transport-discovery/client/client_test.go | 2 +- pkg/transport/discovery_test.go | 4 +-- pkg/transport/entry.go | 8 +++--- pkg/transport/handshake.go | 4 +-- pkg/transport/handshake_test.go | 8 ++---- pkg/transport/manager.go | 11 +++++--- pkg/transport/manager_test.go | 27 ++++++++++--------- pkg/transport/mock.go | 4 +-- 12 files changed, 40 insertions(+), 39 deletions(-) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index 3d4c283531..4a640b8ef2 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -128,7 +128,6 @@ func (c *channel) Close() error { return nil } - func (c *channel) SetDeadline(t time.Time) error { c.deadline = t return nil diff --git a/pkg/messaging/channel_test.go b/pkg/messaging/channel_test.go index c519f18161..aa117408af 100644 --- a/pkg/messaging/channel_test.go +++ b/pkg/messaging/channel_test.go @@ -137,7 +137,7 @@ func handshakeChannel(t *testing.T, c *channel, pk cipher.PubKey, sk cipher.SecK noiseConf := noise.Config{ LocalSK: sk, LocalPK: pk, - RemotePK: c.Local(), + RemotePK: c.link.Local(), Initiator: false, } diff --git a/pkg/node/rpc_client.go b/pkg/node/rpc_client.go index 996c4dd5f5..385ce5c9e6 100644 --- a/pkg/node/rpc_client.go +++ b/pkg/node/rpc_client.go @@ -153,7 +153,7 @@ func NewMockRPCClient(r *rand.Rand, maxTps int, maxRules int) (cipher.PubKey, RP for i := range tps { remotePK, _ := cipher.GenerateKeyPair() tps[i] = &TransportSummary{ - ID: transport.MakeTransportID(localPK, remotePK, types[r.Int()%len(types)]), + ID: transport.MakeTransportID(localPK, remotePK, types[r.Int()%len(types)], true), Local: localPK, Remote: remotePK, Type: types[r.Int()%len(types)], @@ -314,7 +314,7 @@ func (mc *mockRPCClient) Transport(tid uuid.UUID) (*TransportSummary, error) { // AddTransport implements RPCClient. func (mc *mockRPCClient) AddTransport(remote cipher.PubKey, tpType string, public bool, _ time.Duration) (*TransportSummary, error) { summary := &TransportSummary{ - ID: transport.MakeTransportID(mc.s.PubKey, remote, tpType), + ID: transport.MakeTransportID(mc.s.PubKey, remote, tpType, public), Local: mc.s.PubKey, Remote: remote, Type: tpType, diff --git a/pkg/route-finder/client/mock.go b/pkg/route-finder/client/mock.go index 83d09c0bf5..57914181e3 100644 --- a/pkg/route-finder/client/mock.go +++ b/pkg/route-finder/client/mock.go @@ -33,7 +33,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.MakeTransportID(src, dst, ""), + Transport: transport.MakeTransportID(src, dst, "", true), }, }, }, []routing.Route{ @@ -41,7 +41,7 @@ func (r *mockClient) PairedRoutes(src, dst cipher.PubKey, minHops, maxHops uint1 &routing.Hop{ From: src, To: dst, - Transport: transport.MakeTransportID(src, dst, ""), + Transport: transport.MakeTransportID(src, dst, "", true), }, }, }, nil diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index f1f67b9d88..a2529961fa 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -24,7 +24,7 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() entry := &transport.Entry{ - ID: transport.MakeTransportID(pk1, testPubKey, "messaging"), + ID: transport.MakeTransportID(pk1, testPubKey, "messaging", true), Type: "messaging", Public: true, } diff --git a/pkg/transport/discovery_test.go b/pkg/transport/discovery_test.go index dc16337d0d..db01261433 100644 --- a/pkg/transport/discovery_test.go +++ b/pkg/transport/discovery_test.go @@ -18,7 +18,7 @@ func ExampleNewDiscoveryMock() { if err := dc.RegisterTransports(context.TODO(), sEntry); err == nil { fmt.Println("RegisterTransport success") } else { - fmt.Println(Ok.Error()) + fmt.Println(err.Error()) } if entryWS, err := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID); err == nil { @@ -36,7 +36,7 @@ func ExampleNewDiscoveryMock() { if _, err := dc.UpdateStatuses(context.TODO(), &Status{}); err == nil { fmt.Println("UpdateStatuses success") } else { - fmt.Println(Ok.Error()) + fmt.Println(err.Error()) } // Output: RegisterTransport success diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 24af3de755..bfc61799bb 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -30,7 +30,7 @@ type Entry struct { // NewEntry constructs *Entry func NewEntry(edgeA, edgeB cipher.PubKey, tpType string, public bool) *Entry { return &Entry{ - ID: MakeTransportID(edgeA, edgeB, tpType), + ID: MakeTransportID(edgeA, edgeB, tpType, public), EdgeKeys: SortPubKeys(edgeA, edgeB), Type: tpType, Public: public, @@ -48,7 +48,7 @@ func (e *Entry) Edges() [2]cipher.PubKey { // SetEdges sets edges of Entry func (e *Entry) SetEdges(edges [2]cipher.PubKey) { - e.ID = MakeTransportID(edges[0], edges[1], e.Type) + e.ID = MakeTransportID(edges[0], edges[1], e.Type, e.Public) e.EdgeKeys = SortPubKeys(edges[0], edges[1]) } @@ -113,14 +113,14 @@ func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) error { if err == nil { se.Signatures[idx] = se.Entry.Signature(secKey) } - return Ok + return err } // Signature gets Signature for a given PubKey from correct position func (se *SignedEntry) Signature(pk cipher.PubKey) (cipher.Sig, error) { idx, err := se.Index(pk) if err != nil { - return cipher.Sig{}, Ok + return cipher.Sig{}, err } return se.Signatures[idx], nil } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 6d238484ff..35b8b92310 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -32,7 +32,7 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. func settlementInitiatorHandshake(public bool) settlementHandshake { return func(tm *Manager, tr Transport) (*Entry, error) { entry := &Entry{ - ID: MakeTransportID(tr.Edges()[0], tr.Edges()[1], tr.Type()), + ID: MakeTransportID(tr.Edges()[0], tr.Edges()[1], tr.Type(), public), EdgeKeys: tr.Edges(), Type: tr.Type(), Public: public, @@ -43,7 +43,7 @@ func settlementInitiatorHandshake(public bool) settlementHandshake { sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { - return nil, fmt.Errorf("settlementInitiatorHandshake NewSignedEntry: %s\n sEntry: %v\n", err, sEntry) + return nil, fmt.Errorf("settlementInitiatorHandshake NewSignedEntry: %s\n sEntry: %v", err, sEntry) } if err := json.NewEncoder(tr).Encode(sEntry); err != nil { diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index 95c75f1052..f9a9e1b76a 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -105,7 +105,7 @@ func Example_validateEntry() { entry := NewEntry(pk1, pk2, "mock", true) sEntry := NewSignedEntry(entry, pk1, sk1) if err := validateSignedEntry(sEntry, tr, pk1); err != nil { - fmt.Println(Ok.Error()) + fmt.Println(err.Error()) } // Output: invalid entry edges @@ -255,7 +255,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { tpType := "mock" entry := &Entry{ - ID: MakeTransportID(mockEnv.pk1, mockEnv.pk2, tpType), + ID: MakeTransportID(mockEnv.pk1, mockEnv.pk2, tpType, true), EdgeKeys: SortPubKeys(mockEnv.pk1, mockEnv.pk2), Type: tpType, Public: true, @@ -313,12 +313,9 @@ func Example_verifySig() { func Example_settlementInitiatorHandshake() { mockEnv := newHsMockEnv() - // uid := MakeTransportID(mockEnv.pk1, mockEnv.pk2, "mock") - initHandshake := settlementInitiatorHandshake(true) respondHandshake := settlementResponderHandshake - // resultCh := make(chan hsResult) errCh := make(chan error) go func() { entry, err := initHandshake(mockEnv.m1, mockEnv.tr1) @@ -327,7 +324,6 @@ func Example_settlementInitiatorHandshake() { errCh <- err } errCh <- nil - // resultCh <- hsResult{entry, err} }() go func() { diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index e3ae736b22..3d532db5c8 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -214,13 +214,18 @@ func (tm *Manager) Serve(ctx context.Context) error { return nil } -// MakeTransportID generates uuid.UUID from pair of keys. +// MakeTransportID generates uuid.UUID from pair of keys + type + public // Generated uuid is: // - always the same for a given pair // - GenTransportUUID(keyA,keyB) == GenTransportUUID(keyB, keyA) -func MakeTransportID(keyA, keyB cipher.PubKey, tpType string) uuid.UUID { +func MakeTransportID(keyA, keyB cipher.PubKey, tpType string, public bool) uuid.UUID { keys := SortPubKeys(keyA, keyB) - return uuid.NewSHA1(uuid.UUID{}, append(append(keys[0][:], keys[1][:]...), []byte(tpType)...)) + if public { + return uuid.NewSHA1(uuid.UUID{}, + append(append(append(keys[0][:], keys[1][:]...), []byte(tpType)...), 1)) + } + return uuid.NewSHA1(uuid.UUID{}, + append(append(append(keys[0][:], keys[1][:]...), []byte(tpType)...), 0)) } // SortPubKeys sorts keys so that least-significant comes first diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 66974afacf..4a4abd7ae4 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -231,42 +231,43 @@ func ExampleSortPubKeys() { // SortPubKeys(keyA, keyB) == SortPubKeys(keyB, keyA) } -// MakeTransportID(keyA,keyB, "type") == MakeTransportID(keyB, keyA, "type") -// GetTrasportUUID(keyA,keyB) is always the same for a given pair -// MakeTransportID(keyA, keyA) works for equal keys -// MakeTransportID(keyA,keyB, "type") != MakeTransportID(keyB, keyA, "type") func ExampleMakeTransportID() { keyA, _ := cipher.GenerateKeyPair() keyB, _ := cipher.GenerateKeyPair() - uuidAB := MakeTransportID(keyA, keyB, "type") + uuidAB := MakeTransportID(keyA, keyB, "type", true) for i := 0; i < 256; i++ { - if MakeTransportID(keyA, keyB, "type") != uuidAB { - fmt.Printf("uuid is unstable") + if MakeTransportID(keyA, keyB, "type", true) != uuidAB { + fmt.Println("uuid is unstable") break } } fmt.Printf("uuid is stable\n") - uuidBA := MakeTransportID(keyB, keyA, "type") + uuidBA := MakeTransportID(keyB, keyA, "type", true) if uuidAB == uuidBA { - fmt.Printf("uuid is bidirectional\n") + fmt.Println("uuid is bidirectional") } else { fmt.Printf("keyA = %v\n keyB=%v\n uuidAB=%v\n uuidBA=%v\n", keyA, keyB, uuidAB, uuidBA) } - _ = MakeTransportID(keyA, keyA, "type") // works for equal keys - fmt.Printf("works for equal keys\n") + _ = MakeTransportID(keyA, keyA, "type", true) // works for equal keys + fmt.Println("works for equal keys") - if MakeTransportID(keyA, keyB, "type") != MakeTransportID(keyA, keyB, "another_type") { - fmt.Printf("uuid is different for different types") + if MakeTransportID(keyA, keyB, "type", true) != MakeTransportID(keyA, keyB, "another_type", true) { + fmt.Println("uuid is different for different types") + } + + if MakeTransportID(keyA, keyB, "type", true) != MakeTransportID(keyA, keyB, "type", false) { + fmt.Println("uuid is different for public and private transports") } // Output: uuid is stable // uuid is bidirectional // works for equal keys // uuid is different for different types + // uuid is different for public and private transports } func ExampleManager_CreateTransport() { diff --git a/pkg/transport/mock.go b/pkg/transport/mock.go index af2d5f052a..6098223aa3 100644 --- a/pkg/transport/mock.go +++ b/pkg/transport/mock.go @@ -77,8 +77,8 @@ func (f *MockFactory) Type() string { // MockTransport is a transport that accepts custom writers and readers to use them in Read and Write // operations type MockTransport struct { - rw io.ReadWriteCloser - edges [2]cipher.PubKey + rw io.ReadWriteCloser + edges [2]cipher.PubKey context context.Context } From e867da64c7bb9ba00fe92085875a887a309c81a9 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Fri, 5 Apr 2019 12:01:56 +0300 Subject: [PATCH 18/26] Merged with mainnet --- Makefile | 19 ++++++++++++++++--- cmd/skywire-cli/commands/tpdisc/root.go | 2 +- pkg/messaging/client.go | 1 + pkg/transport/handshake.go | 1 - pkg/transport/manager.go | 8 ++++++++ 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index bb8253ef70..ed67d1a0c1 100644 --- a/Makefile +++ b/Makefile @@ -18,13 +18,13 @@ check: lint test ## Run linters and tests build: dep host-apps bin ## Install dependencies, build apps and binaries. `go build` with ${OPTS} run: stop build config ## Run skywire-node on host - ./skywire-node + ./skywire-node skywire.json stop: ## Stop running skywire-node on host -bash -c "kill $$(ps aux |grep '[s]kywire-node' |awk '{print $$2}')" config: ## Generate skywire.json - -./skywire-cli gen-config -o ./skywire.json -r + -./skywire-cli node gen-config -o ./skywire.json -r clean: ## Clean project: remove created binaries and apps -rm -rf ./apps @@ -33,6 +33,12 @@ clean: ## Clean project: remove created binaries and apps install: ## Install `skywire-node`, `skywire-cli`, `manager-node`, `therealssh-cli` ${OPTS} go install ./cmd/skywire-node ./cmd/skywire-cli ./cmd/manager-node ./cmd/therealssh-cli +rerun: stop + ${OPTS} go build -race -o ./skywire-node ./cmd/skywire-node + -./skywire-cli node gen-config -o ./skywire.json -r + perl -pi -e 's/localhost//g' ./skywire.json + ./skywire-node skywire.json + lint: ## Run linters. Use make install-linters first ${OPTS} golangci-lint run -c .golangci.yml ./... @@ -138,7 +144,8 @@ docker-bin: ## Build `skywire-node`, `skywire-cli`, `manager-node`, `therealssh- ${DOCKER_OPTS} go build -race -o ./node/skywire-node ./cmd/skywire-node docker-volume: docker-apps docker-bin bin ## Prepare docker volume for dockerized skywire-node - -./skywire-cli gen-config -o ./node/skywire.json + -./skywire-cli node gen-config -o ./node/skywire.json -r + perl -pi -e 's/localhost//g' ./node/skywire.json # To make node accessible from outside with skywire-cli docker-run: docker-clean docker-image docker-network docker-volume ## Run dockerized skywire-node ${DOCKER_NODE} in image ${DOCKER_IMAGE} with network ${DOCKER_NETWORK} docker run -it -v $(shell pwd)/node:/sky --network=${DOCKER_NETWORK} \ @@ -147,6 +154,12 @@ docker-run: docker-clean docker-image docker-network docker-volume ## Run docker docker-stop: ## Stop running dockerized skywire-node ${DOCKER_NODE} -docker container stop ${DOCKER_NODE} +docker-rerun: docker-stop + -./skywire-cli gen-config -o ./node/skywire.json -r + perl -pi -e 's/localhost//g' ./node/skywire.json # To make node accessible from outside with skywire-cli + ${DOCKER_OPTS} go build -race -o ./node/skywire-node ./cmd/skywire-node + docker container start -i ${DOCKER_NODE} + help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/cmd/skywire-cli/commands/tpdisc/root.go b/cmd/skywire-cli/commands/tpdisc/root.go index e0fb6399df..d72036e914 100644 --- a/cmd/skywire-cli/commands/tpdisc/root.go +++ b/cmd/skywire-cli/commands/tpdisc/root.go @@ -70,7 +70,7 @@ func printTransportEntries(entries ...*transport.EntryWithStatus) { internal.Catch(err) for _, e := range entries { _, err := fmt.Fprintf(w, "%s\t%s\t%t\t%d\t%t\t%s\t%s\t%t\t%t\n", - e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.Edges[0], e.Entry.Edges[1], e.Statuses[0], e.Statuses[1]) + e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.Edges()[0], e.Entry.Edges()[1], e.Statuses[0], e.Statuses[1]) internal.Catch(err) } internal.Catch(w.Flush()) diff --git a/pkg/messaging/client.go b/pkg/messaging/client.go index 1abb138044..73278339e8 100644 --- a/pkg/messaging/client.go +++ b/pkg/messaging/client.go @@ -144,6 +144,7 @@ func (c *Client) Accept(ctx context.Context) (transport.Transport, error) { func (c *Client) Dial(ctx context.Context, remote cipher.PubKey) (transport.Transport, error) { entry, err := c.dc.Entry(ctx, remote) if err != nil { + fmt.Printf("Dial with remote = %v\n", remote) return nil, fmt.Errorf("get entry failure: %s", err) } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 35b8b92310..b82e50ba04 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -16,7 +16,6 @@ func (handshake settlementHandshake) Do(tm *Manager, tr Transport, timeout time. var entry *Entry errCh := make(chan error, 1) go func() { - fmt.Printf("IMMA HERE") e, err := handshake(tm, tr) entry = e errCh <- err diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 3d532db5c8..0cd86c3d41 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -3,6 +3,7 @@ package transport import ( "context" "errors" + "fmt" "math/big" "strings" "sync" @@ -347,6 +348,13 @@ func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tp } func (tm *Manager) dialTransport(ctx context.Context, factory Factory, remote cipher.PubKey, public bool) (Transport, *Entry, error) { + + fmt.Printf("Manager.dialTransport: %v %v\n", tm.Local(), remote) + + if tm.Local() == remote { + fmt.Println("local and remote are equal. No need to dial") + } + tr, err := factory.Dial(ctx, remote) if err != nil { return nil, nil, err From 38e52706d9d1c1df3fbdf4af282c43f5d6076702 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Fri, 5 Apr 2019 16:14:34 +0300 Subject: [PATCH 19/26] Still WIP --- pkg/transport/entry.go | 13 +++++++------ pkg/transport/handshake.go | 3 +++ pkg/transport/manager.go | 6 +++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index bfc61799bb..9d0c6cc2ed 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -69,13 +69,14 @@ func (e *Entry) String() string { return res } -// ToBinary returns binary representation of a Signature. +// ToBinary returns binary representation of an Entry func (e *Entry) ToBinary() []byte { - bEntry := e.ID[:] - for _, edge := range e.Edges() { - bEntry = append(bEntry, edge[:]...) - } - return append(bEntry, []byte(e.Type)...) + edges := e.Edges() + return append( + append( + append(e.ID[:], edges[0][:]...), + edges[1][:]...), + []byte(e.Type)...) } // Signature returns signature for Entry calculated from binary diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index b82e50ba04..e76e3f0936 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -83,6 +83,9 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, errRemote } if err := validateSignedEntry(sEntry, tr, remote); err != nil { + tm.Logger.Infof("validateSignedEntry: sEntry %v\n tr: %v\n remote: %v\n", sEntry, tr, remote) + tm.Logger.Infof("validateSignedEntry: Edges: %v\n", tr.Edges()) + tm.Logger.Infof("validateSignedEntry: tm.config.PubKey: %v", tm.config.PubKey) return nil, err } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 0cd86c3d41..378321b0d0 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -375,8 +375,12 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } + tm.Logger.Infof("Trying to handshake with: %T %v\n", tr, tr) + tm.Logger.Infof("Handshake from factory: %T %v\n", factory, factory) + tm.Logger.Infof("Handshake: tr.Edges(): %v\n tr.Type(): %v\n", tr.Edges(), tr.Type()) + var handshake settlementHandshake = settlementResponderHandshake - entry, err := handshake.Do(tm, tr, time.Minute) + entry, err := handshake.Do(tm, tr, 30*time.Second) if err != nil { tr.Close() return nil, err From 8200dbc8ea11873d4395d91f4f0a5ab6be66df82 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 8 Apr 2019 06:31:12 +0300 Subject: [PATCH 20/26] Changes: 1.pkg/setup/setup_protocol_test.go: added Examples for setup.Protocol --- go.mod | 41 ++- go.sum | 264 ++++++++++++++++++ pkg/app/packet.go | 30 +- pkg/app/packet_test.go | 21 ++ pkg/manager/user.go | 2 +- pkg/node/node.go | 2 +- pkg/router/route_manager.go | 8 +- pkg/router/route_manager_test.go | 16 +- pkg/router/router.go | 32 +-- pkg/router/router_test.go | 46 +-- pkg/setup/protocol.go | 4 +- pkg/setup/setup_protocol_test.go | 126 +++++++++ pkg/transport-discovery/client/client_test.go | 2 +- pkg/transport/handshake.go | 20 +- pkg/transport/manager_test.go | 2 +- 15 files changed, 534 insertions(+), 82 deletions(-) create mode 100644 pkg/app/packet_test.go create mode 100644 pkg/setup/setup_protocol_test.go diff --git a/go.mod b/go.mod index 30d355c698..cf3596c80d 100644 --- a/go.mod +++ b/go.mod @@ -3,28 +3,63 @@ module github.com/skycoin/skywire go 1.12 require ( + github.com/FiloSottile/vendorcheck v0.0.0-20160511012517-d6d54d1b5894 // indirect + github.com/Masterminds/semver v1.4.2 // indirect + github.com/Masterminds/vcs v1.13.0 // indirect + github.com/acroca/go-symbols v0.1.1 // indirect + github.com/armon/go-radix v1.0.0 // indirect github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 + github.com/boltdb/bolt v1.3.1 // indirect + github.com/calebthompson/ftree v0.2.0 // indirect + github.com/dvyukov/go-fuzz v0.0.0-20190402070214-9cfa592d5792 // indirect + github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect + github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607 // indirect + github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6 // indirect github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 github.com/go-chi/chi v4.0.2+incompatible + github.com/go-delve/delve v1.2.0 // indirect + github.com/godbus/dbus v4.1.0+incompatible // indirect + github.com/golang/dep v0.5.1 // indirect + github.com/golangci/golangci-lint v1.16.0 // indirect github.com/google/uuid v1.1.1 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.1.3 // indirect + github.com/hanwen/go-fuse v1.0.0 // indirect github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d - github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/kr/pretty v0.1.0 // indirect + github.com/jmank88/nuts v0.3.0 // indirect + github.com/karrick/godirwalk v1.8.0 // indirect + github.com/keegancsmith/rpc v1.1.0 // indirect + github.com/kr/fs v0.1.0 // indirect github.com/kr/pty v1.1.3 github.com/mattn/go-colorable v0.1.1 // indirect + github.com/mattn/go-sqlite3 v1.10.0 // indirect + github.com/mdempsky/gocode v0.0.0-20190203001940-7fb65232883f // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mibk/dupl v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 + github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443 // indirect + github.com/oniony/TMSU v0.7.4 // indirect + github.com/pkg/errors v0.8.1 // indirect + github.com/ramya-rao-a/go-outline v0.0.0-20181122025142-7182a932836a // indirect + github.com/rogpeppe/godef v1.1.1 // indirect + github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 // indirect github.com/sirupsen/logrus v1.4.0 // indirect github.com/skycoin/skycoin v0.25.1 github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.3 // indirect + github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 // indirect + github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997 // indirect + github.com/stephens2424/writerset v1.0.2 // indirect github.com/stretchr/testify v1.3.0 + github.com/tools/godep v0.0.0-20180126220526-ce0bfadeb516 // indirect + github.com/uudashr/gopkgs v2.0.1+incompatible // indirect + github.com/visualfc/fastmod v0.0.0-20190131104758-c069a47540eb // indirect + github.com/visualfc/gocode v0.0.0-20190319040811-fab173807d9b // indirect + github.com/visualfc/gotools v0.0.0-20190218124934-6d12497f1bd5 // indirect go.etcd.io/bbolt v1.3.2 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c + golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87 golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc // indirect golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/go.sum b/go.sum index 2d4bbd63e1..fded45e4e4 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,127 @@ +9fans.net/go v0.0.0-20181112161441-237454027057 h1:OcHlKWkAMJEF1ndWLGxp5dnJQkYM/YImUOvsBoz6h5E= +9fans.net/go v0.0.0-20181112161441-237454027057/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/FiloSottile/vendorcheck v0.0.0-20160511012517-d6d54d1b5894 h1:qPUfImRXGY2gSwpT9nsRkJ/k0NqhglgF0o8ks4dEOc0= +github.com/FiloSottile/vendorcheck v0.0.0-20160511012517-d6d54d1b5894/go.mod h1:6ESDF5hks2bKFzhGWxWv9Aalqz+Q2TJAPljRwfjpQ3A= +github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA= +github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2 h1:HTOmFEEYrWi4MW5ZKUx6xfeyM10Sx3kQF65xiQJMPYA= +github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/acroca/go-symbols v0.1.1 h1:q3IzaMNYocw/Bnc2a8jkXf0hM3+POfLoq30x8HYuaPE= +github.com/acroca/go-symbols v0.1.1/go.mod h1:RKAIDWtcELAw6/wjNJGWRYZ7QEinSWoJeJ2H5cfK6AM= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/ayuryshev/arena v0.0.0-20190302131351-028723a0b932 h1:pM2ppQJfvZOznzaU9ZAX9EwzuOh/sKoMUVmR+ybiEIM= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/calebthompson/ftree v0.2.0 h1:jMwReBavkpqHUY9g0COuWTHxvqhRcpCo9Xh3Z2QnFUA= +github.com/calebthompson/ftree v0.2.0/go.mod h1:nh/clP4boz45PfchjE6vhCbYw5SdT18XNUkQWwgZvZo= +github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5 h1:rIXlvz2IWiupMFlC45cZCXZFvKX/ExBcSLrDy2G0Lp8= +github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ= +github.com/cpuguy83/go-md2man v1.0.8/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY= 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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/derekparker/delve v1.2.0 h1:kxzyrc2Di/Yxw+sD+H2I9rzIqWjpTSB9Ve4guZpfG6Y= +github.com/dvyukov/go-fuzz v0.0.0-20190402070214-9cfa592d5792 h1:UJcJo+Ja8EnbMijmxI/i4fF9R2YrdK1TAPH8zNgJRSk= +github.com/dvyukov/go-fuzz v0.0.0-20190402070214-9cfa592d5792/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607 h1:cTavhURetDkezJCvxFggiyLeP40Mrk/TtVg2+ycw1Es= +github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607/go.mod h1:Cg4fM0vhYWOZdgM7RIOSTRNIc8/VT7CXClC3Ni86lu4= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.6.0 h1:66qjqZk8kalYAvDRtM1AdAJQI0tj4Wrue3Eq3B3pmFU= +github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6 h1:iXJdM8Uob6EPOG/PFr5q0J124ysiZdJfACHqICBb3b8= +github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6/go.mod h1:p2/x7bnOQsbq/deXsDIlj2yLiKFGPkD2nuoYqwn8R4Y= +github.com/fatih/structtag v1.0.0 h1:pTHj65+u3RKWYPSGaU290FpI/dXxTaHdVwVwbcPKmEc= +github.com/fatih/structtag v1.0.0/go.mod h1:IKitwq45uXL/yqi5mYghiD3w9H6eTOvI9vnk8tXMphA= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= +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/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs= github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-critic/go-critic v0.0.0-20181204210945-ee9bf5809ead h1:qwmAYufKDopQnFdeMw+iHJVxAd2CbF+VFKHyJJwnPKk= +github.com/go-critic/go-critic v0.0.0-20181204210945-ee9bf5809ead/go.mod h1:3MzXZKJdeXqdU9cj+rvZdNiN7SZ8V9OjybF8loZDmHU= +github.com/go-delve/delve v1.2.0 h1:uwGyfYO0WsWqbnDWvxCBKOr2qFLpii3tLxwM+fTJs70= +github.com/go-delve/delve v1.2.0/go.mod h1:yP+LD36s/ud5nm4lsQY0TwNhYu2PAwk6xItz+442j74= +github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= +github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-toolsmith/astcast v0.0.0-20181028201508-b7a89ed70af1 h1:h+1eMw+tZAlgTVclcVN0/rdPaBI/RUzG0peblT6df+Q= +github.com/go-toolsmith/astcast v0.0.0-20181028201508-b7a89ed70af1/go.mod h1:TEo3Ghaj7PsZawQHxT/oBvo4HK/sl1RcuUHDKTTju+o= +github.com/go-toolsmith/astcopy v0.0.0-20180903214859-79b422d080c4 h1:wVs9OMjICHbAryp9hcIuWqUOi+NqEbUSZy9zMe3W//I= +github.com/go-toolsmith/astcopy v0.0.0-20180903214859-79b422d080c4/go.mod h1:c9CPdq2AzM8oPomdlPniEfPAC6g1s7NqZzODt8y6ib8= +github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6 h1:aTBUNRTatDDU24gbOEKEoLiDwxtc98ga6K/iMTm6fvs= +github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086 h1:EIMuvbE9fbtQtimdLe5yeXjuC5CeKbQt8zH6GwtIrhM= +github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= +github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30 h1:zRJPftZJNLPDiOtvYbFRwjSbaJAcVOf80TeEmWGe2kQ= +github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= +github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= +github.com/go-toolsmith/strparse v0.0.0-20180903215201-830b6daa1241 h1:ZRDeQioMGTBLeJxcPxXfFifEUgYxzR7fXw7w2WR+1bo= +github.com/go-toolsmith/strparse v0.0.0-20180903215201-830b6daa1241/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v0.0.0-20181030061450-d63dc7650676 h1:6Qrsp0+25KEkaS2bB26UE0giFgRrIc8mYXboDL5OVMA= +github.com/go-toolsmith/typep v0.0.0-20181030061450-d63dc7650676/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= +github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/dep v0.5.1 h1:gKbgq5zV8Ec2fR54yr8fmFPK0v2idQ46kNZniWUtZsc= +github.com/golang/dep v0.5.1/go.mod h1:6RZ2Wai7dSWk7qL55sDYk+8UPFqcW7all2KDBraPPFA= +github.com/golang/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:14pqJU+T8BQvc6B0Ed0UJaMPoZR3WJ0P1NAIP+jjx9M= +github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +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/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6 h1:i2jIkQFb8RG45DuQs+ElyROY848cSJIoIkBM+7XXypA= +github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/go-tools v0.0.0-20180109140146-af6baa5dc196 h1:9rtVlONXLF1rJZzvLt4tfOXtnAFUEhxCJ64Ibzj6ECo= +github.com/golangci/go-tools v0.0.0-20180109140146-af6baa5dc196/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= +github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= +github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= +github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= +github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= +github.com/golangci/gofmt v0.0.0-20181105071733-0b8337e80d98 h1:ir6/L2ZOJfFrJlOTsuf/hlzdPuUwXV/VzkSlgS6f1vs= +github.com/golangci/gofmt v0.0.0-20181105071733-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.16.0 h1:PcWAN9JHflZzJQaZVY1JXZE0Tgjq+jO2v4QLqJ/Azvw= +github.com/golangci/golangci-lint v1.16.0/go.mod h1:uySrAxrUmZYnxyccYSnwuAEm+3144Zg5IAUueIW8+fA= +github.com/golangci/golangci-lint/vendor/github.com/kisielk/gotool v0.0.0-20190402065613-de1d1ad903cd h1:xJwt2dkhFdX4mX27a38SBPvRMJIQhDJcx5/cmM0P/0I= +github.com/golangci/gosec v0.0.0-20180901114220-66fb7fc33547 h1:qMomh8bv+kDazm1dSLZ9S3zZ2PJZMHL4ilfBjxFOlmI= +github.com/golangci/gosec v0.0.0-20180901114220-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= +github.com/golangci/ineffassign v0.0.0-20180808204949-2ee8f2867dde h1:qEGp3ZF1Qw6TkbWKn6GdJ12Ssu/CpJBaBcJ4hrUjrSo= +github.com/golangci/ineffassign v0.0.0-20180808204949-2ee8f2867dde/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/lint-1 v0.0.0-20180610141402-4bf9709227d1 h1:PHK2kIh21Zt4IcG0bBRzQwEDVKF64LnkoSXnm8lfJUk= +github.com/golangci/lint-1 v0.0.0-20180610141402-4bf9709227d1/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= @@ -16,12 +130,29 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU= github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc= +github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianthehat/godef v0.0.0-20181121200540-1ef9e6bcd64c h1:ilHBod5iwnm8drLfHO+B8z/k8drykf1jDFZgojTMrb0= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmank88/nuts v0.3.0 h1:UZUboV1LXVkBUTHLRTEZrDfAL7QYgj9jEsBCiJHrxEM= +github.com/jmank88/nuts v0.3.0/go.mod h1:kTf5cyoLibZUQg9Lns/gteKO1d/5XrhacD1QVKviAKk= +github.com/karrick/godirwalk v1.8.0 h1:ycpSqVon/QJJoaT1t8sae0tp1Stg21j+dyuS7OoagcA= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/keegancsmith/rpc v1.1.0 h1:bXVRk3EzbtrEegTGKxNTc+St1lR7t/Z1PAO8misBnCc= +github.com/keegancsmith/rpc v1.1.0/go.mod h1:Xow74TKX34OPPiPCdz6x1o9c0SCxRqGxDuKGk7ZOo8s= +github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -29,48 +160,181 @@ github.com/kr/pty v1.1.3 h1:/Um6a/ZmD5tF7peoOJ5oN5KMQ0DrGVQSXLNwyckutPk= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54= +github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.0-20170327083344-ded68f7a9561/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mdempsky/gocode v0.0.0-20190203001940-7fb65232883f h1:ee+twVCignaZjt7jpbMSLxAeTN/Nfq9W/nm91E7QO1A= +github.com/mdempsky/gocode v0.0.0-20190203001940-7fb65232883f/go.mod h1:hltEC42XzfMNgg0S1v6JTywwra2Mu6F6cLR03debVQ8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mibk/dupl v1.0.0 h1:aZc3jqrF9n0tUHwHt/+jsRxA8cRgA0Gdl56M7W7PoqE= +github.com/mibk/dupl v1.0.0/go.mod h1:pCr4pNxxIbFGvtyCOi0c7LVjmV6duhKWV+ex5vh38ME= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= +github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238 h1:+MZW2uvHgN8kYvksEN3f7eFL2wpzk0GxmlFsMybWc7E= +github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663 h1:Ri1EhipkbhWsffPJ3IPlrb4SkTOPa2PfRXp3jchBczw= +github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443 h1:+2OJrU8cmOstEoh0uQvYemRGVH1O6xtO2oANUWHFnP0= +github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443/go.mod h1:JbxfV1Iifij2yhRjXai0oFrbpxszXHRx1E5RuM26o4Y= +github.com/oniony/TMSU v0.7.4 h1:vCogZaPLJc+4FL7oTt4aKtw0c8sIZMPfqsWfy9p9K+E= +github.com/oniony/TMSU v0.7.4/go.mod h1:e+jNOLsdK7K38lfBAwc/HFWE5Z2z7pcxhVTEVyvrAMk= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM= +github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b h1:8uaXtUkxiy+T/zdLWuxa/PG4so0TPZDZfafFNNSaptE= +github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v0.0.0-20170413231811-06b906832ed0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/ramya-rao-a/go-outline v0.0.0-20181122025142-7182a932836a h1:rJS9v8WlLfIQ/22PlTXc47p5jB8RaY9XnTkX8Uols7w= +github.com/ramya-rao-a/go-outline v0.0.0-20181122025142-7182a932836a/go.mod h1:1WL5IqM+CnRCAbXetRnL1YVoS9KtU2zMhOi/5oAVPo4= +github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/godef v1.1.1 h1:NujOtt9q9vIClRTB3sCZpavac+NMRaIayzrcz1h4fSE= +github.com/rogpeppe/godef v1.1.1/go.mod h1:oEo1eMy1VUEHUzUIX4F7IqvMJRiz9UId44mvnR8oPlQ= +github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 h1:tnWWLf0nI2TI62Wd/ZOea4XYqE+y1sf2pdm+VItsc0c= +github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353/go.mod h1:5HStXbIikwtDAgAIqiQIqVgMn7mlvZa6PTpwiAVYGYg= +github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirupsen/logrus v0.0.0-20180523074243-ea8897e79973/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.4.0 h1:yKenngtzGh+cUSSh6GWbxW2abRqhYUSR/t/6+2QqNvE= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/skycoin/skycoin v0.25.1 h1:4tYXHiTX00pFydjUWHmqSnAYfrJ59xsa9pfmEu7tki8= github.com/skycoin/skycoin v0.25.1/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw= +github.com/spf13/afero v1.1.0 h1:bopulORc2JeYaxfHLvJa5NzxviA9PoWhpiiJkru7Ji4= +github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cobra v0.0.0-20170417170307-b6cb39589372/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig= +github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170417173400-9e4c21054fa1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso= +github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 h1:iD+PFTQwKEmbwSdwfvP5ld2WEI/g7qbdhmHJ2ASfYGs= +github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= +github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997 h1:LF81AGV63kJoxjmSgQPT8FARAMHeY46CYQ4TNoVDWHM= +github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997/go.mod h1:EM2T8YDoTCvGXbEpFHxarbpv7VE26QD1++Cb1Pbh7Gs= +github.com/stephens2424/writerset v1.0.2 h1:znRLgU6g8RS5euYRcy004XeE4W+Tu44kALzy7ghPif8= +github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tools/godep v0.0.0-20180126220526-ce0bfadeb516 h1:h4a8ZFxjlRVGsFGP4l/AdnoUYcF3pfxzyepS3oKZ8mE= +github.com/tools/godep v0.0.0-20180126220526-ce0bfadeb516/go.mod h1:OGh2HQGYVW+2+ZdB+DgJhI75kivkKWtVcIxI/pesDsY= +github.com/uudashr/gopkgs v2.0.1+incompatible h1:SuNs9p/XbGcQezR7SguZrZzxqCQozxtd/N8UKBWbWjk= +github.com/uudashr/gopkgs v2.0.1+incompatible/go.mod h1:MtCdKVJkxW7hNKWXPNWfpaeEp8+Ml3Q8myb4yWhn2Hg= +github.com/visualfc/fastmod v0.0.0-20190131104758-c069a47540eb h1:SsMc1pWQd9VeSFNtMJi5Y4DIhAt50JgA5e+a/1JvrNM= +github.com/visualfc/fastmod v0.0.0-20190131104758-c069a47540eb/go.mod h1:qklLSKOIVNIn5SdfGlics3Ljx4kOC29a2gwOS+NjDnQ= +github.com/visualfc/gocode v0.0.0-20190319040811-fab173807d9b h1:4mjeewpDQGUq1j+8tZFaM7Zi7niKRGg4QQdzdd0sJg4= +github.com/visualfc/gocode v0.0.0-20190319040811-fab173807d9b/go.mod h1:jpZqxVZ6mC+EjvX9RrJnIKbM40y/DSWI8bisCpS8Tfw= +github.com/visualfc/gotools v0.0.0-20190218124934-6d12497f1bd5 h1:2HHOotezuYHn1MPMA8CwQtlHNCXDP4byVAChu8tPeoQ= +github.com/visualfc/gotools v0.0.0-20190218124934-6d12497f1bd5/go.mod h1:L4JCuK2/abY1jUXNDGB3gS9uWSQut22gKWkTe1R8b70= go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +golang.org/x/arch v0.0.0-20171004143515-077ac972c2e4 h1:TP7YcWHbnFq4v8/3wM2JwgM0SRRtsYJ7Z6Oj0arz2bs= +golang.org/x/arch v0.0.0-20171004143515-077ac972c2e4/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= +golang.org/x/crypto v0.0.0-20180614174826-fd5f17ee7299/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5 h1:bselrhR0Or1vomJZC8ZIjWtbDmn9OYFLX5Ik9alpJpE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87 h1:yh5/K199RObPR6zqVBYf+AyJuweAqx+fOe9s3cekn1Y= golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87/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/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180614134839-8883426083c0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998= +golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180824175216-6c1c5e93cdc1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181120060634-fc4f04983f62/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181130195746-895048a75ecf/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181205014116-22934f0fdb62/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04 h1:SRYGE+BqJRgY8JH4p2NmwTPeuREKqKYw5IuEmthTHKQ= golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190405141802-1058ed41f41a h1:EFFVpQu3uyLJ7paXZH/6lwZFSJuU5p8ktVXrfcXng6g= +golang.org/x/tools v0.0.0-20190405180640-052fc3cfdbc2 h1:rlaAa9eBBj6AI2C90gKs2Q/XF6YFbBDpGSX+npdfPlk= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170407172122-cd8b52f8269e/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34 h1:B1LAOfRqg2QUyCdzfjf46quTSYUTAK5OCwbh6pljHbM= +mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= +sourcegraph.com/sourcegraph/go-diff v0.5.1-0.20190210232911-dee78e514455 h1:qoQ5Kt+Zm+GXBtz49YwD3juBhr/E0U25jO6bBzxW6NI= +sourcegraph.com/sourcegraph/go-diff v0.5.1-0.20190210232911-dee78e514455/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/pkg/app/packet.go b/pkg/app/packet.go index fe00c6892a..aff7522375 100644 --- a/pkg/app/packet.go +++ b/pkg/app/packet.go @@ -6,6 +6,21 @@ import ( "github.com/skycoin/skywire/pkg/cipher" ) +// Addr implements net.Addr for App connections. +type Addr struct { + PubKey cipher.PubKey `json:"pk"` + Port uint16 `json:"port"` +} + +// Network returns custom skywire Network type. +func (addr *Addr) Network() string { + return "skywire" +} + +func (addr *Addr) String() string { + return fmt.Sprintf("%s:%d", addr.PubKey, addr.Port) +} + // LoopAddr stores addressing parameters of a loop packets. type LoopAddr struct { Port uint16 `json:"port"` @@ -21,18 +36,3 @@ type Packet struct { Addr *LoopAddr `json:"addr"` Payload []byte `json:"payload"` } - -// Addr implements net.Addr for App connections. -type Addr struct { - PubKey cipher.PubKey `json:"pk"` - Port uint16 `json:"port"` -} - -// Network returns custom skywire Network type. -func (addr *Addr) Network() string { - return "skywire" -} - -func (addr *Addr) String() string { - return fmt.Sprintf("%s:%d", addr.PubKey, addr.Port) -} diff --git a/pkg/app/packet_test.go b/pkg/app/packet_test.go new file mode 100644 index 0000000000..d88c71697d --- /dev/null +++ b/pkg/app/packet_test.go @@ -0,0 +1,21 @@ +package app + +import ( + "fmt" + + "github.com/skycoin/skywire/pkg/cipher" +) + +func Example() { + pk := cipher.PubKey{} + addr := Addr{pk, 0} + loopAddr := LoopAddr{0, addr} + + fmt.Println(addr.Network()) + fmt.Printf("%v\n", addr) + fmt.Printf("%v\n", loopAddr) + + //Output: skywire + // {000000000000000000000000000000000000000000000000000000000000000000 0} + // {0 {000000000000000000000000000000000000000000000000000000000000000000 0}} +} diff --git a/pkg/manager/user.go b/pkg/manager/user.go index d0654f27c0..0ac492c5fc 100644 --- a/pkg/manager/user.go +++ b/pkg/manager/user.go @@ -26,7 +26,7 @@ func init() { // User represents a user of the manager. type User struct { Name string - PwSalt []byte + PwSalt []byte/* */ PwHash cipher.SHA256 } diff --git a/pkg/node/node.go b/pkg/node/node.go index 6c1fb168e1..61cf47e921 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -329,7 +329,7 @@ func (node *Node) SpawnApp(config *AppConfig, startCh chan<- struct{}) error { node.startedMu.Lock() if node.startedApps[config.App] != nil { node.startedMu.Unlock() - return fmt.Errorf("App %s is already started", config.App) + return fmt.Errorf("app %s is already started", config.App) } node.startedApps[config.App] = bind diff --git a/pkg/router/route_manager.go b/pkg/router/route_manager.go index 6942b872c9..95768d3cd4 100644 --- a/pkg/router/route_manager.go +++ b/pkg/router/route_manager.go @@ -74,8 +74,8 @@ func (rm *routeManager) RemoveLoopRule(addr *app.LoopAddr) error { } func (rm *routeManager) Serve(rw io.ReadWriter) error { - proto := setup.NewProtocol(rw) - sp, data, err := proto.ReadPacket() + sProto := setup.NewSetupProtocol(rw) + sp, data, err := sProto.ReadPacket() if err != nil { return err } @@ -98,10 +98,10 @@ func (rm *routeManager) Serve(rw io.ReadWriter) error { if err != nil { rm.Logger.Infof("Setup request with type %s failed: %s", sp, err) - return proto.Respond(err) + return sProto.Respond(err) } - return proto.Respond(res) + return sProto.Respond(res) } func (rm *routeManager) addRoutingRules(data []byte) ([]routing.RouteID, error) { diff --git a/pkg/router/route_manager_test.go b/pkg/router/route_manager_test.go index 31196583e9..393e45da63 100644 --- a/pkg/router/route_manager_test.go +++ b/pkg/router/route_manager_test.go @@ -67,10 +67,10 @@ func TestRouteManagerAddRemoveRule(t *testing.T) { errCh <- rm.Serve(out) }() - proto := setup.NewProtocol(in) + sProto := setup.NewSetupProtocol(in) rule := routing.ForwardRule(time.Now(), 3, uuid.New()) - id, err := proto.AddRule(rule) + id, err := sProto.AddRule(rule) require.NoError(t, err) assert.Equal(t, routing.RouteID(1), id) @@ -93,14 +93,14 @@ func TestRouteManagerDeleteRules(t *testing.T) { errCh <- rm.Serve(out) }() - proto := setup.NewProtocol(in) + sProto := setup.NewSetupProtocol(in) rule := routing.ForwardRule(time.Now(), 3, uuid.New()) id, err := rt.AddRule(rule) require.NoError(t, err) assert.Equal(t, 1, rt.Count()) - require.NoError(t, proto.DeleteRule(id)) + require.NoError(t, sProto.DeleteRule(id)) assert.Equal(t, 0, rt.Count()) require.NoError(t, in.Close()) @@ -128,7 +128,7 @@ func TestRouteManagerConfirmLoop(t *testing.T) { errCh <- rm.Serve(out) }() - proto := setup.NewProtocol(in) + sProto := setup.NewSetupProtocol(in) pk, _ := cipher.GenerateKeyPair() rule := routing.AppRule(time.Now(), 3, pk, 3, 2) require.NoError(t, rt.SetRule(2, rule)) @@ -143,7 +143,7 @@ func TestRouteManagerConfirmLoop(t *testing.T) { RouteID: 1, NoiseMessage: []byte("bar"), } - noiseRes, err := proto.ConfirmLoop(ld) + noiseRes, err := sProto.ConfirmLoop(ld) require.NoError(t, err) assert.Equal(t, []byte("foo"), noiseRes) assert.Equal(t, []byte("bar"), noiseMsg) @@ -173,7 +173,7 @@ func TestRouteManagerLoopClosed(t *testing.T) { errCh <- rm.Serve(out) }() - proto := setup.NewProtocol(in) + sProto := setup.NewSetupProtocol(in) pk, _ := cipher.GenerateKeyPair() @@ -190,7 +190,7 @@ func TestRouteManagerLoopClosed(t *testing.T) { RouteID: 1, NoiseMessage: []byte("bar"), } - require.NoError(t, proto.LoopClosed(ld)) + require.NoError(t, sProto.LoopClosed(ld)) assert.Equal(t, uint16(2), inAddr.Port) assert.Equal(t, uint16(3), inAddr.Remote.Port) assert.Equal(t, pk, inAddr.Remote.PubKey) diff --git a/pkg/router/router.go b/pkg/router/router.go index 9053d73a47..1b16749523 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -137,8 +137,8 @@ func (r *Router) ServeApp(conn net.Conn, port uint16, appConf *app.Config) error r.wg.Add(1) defer r.wg.Done() - proto := app.NewProtocol(conn) - if err := r.pm.Open(port, proto); err != nil { + appProto := app.NewProtocol(conn) + if err := r.pm.Open(port, appProto); err != nil { return err } @@ -151,12 +151,12 @@ func (r *Router) ServeApp(conn net.Conn, port uint16, appConf *app.Config) error CloseLoop: r.closeLoop, Forward: r.forwardAppPacket, } - am := &appManager{r.Logger, proto, appConf, callbacks} + am := &appManager{r.Logger, appProto, appConf, callbacks} err := am.Serve() - for _, port := range r.pm.AppPorts(proto) { + for _, port := range r.pm.AppPorts(appProto) { for _, addr := range r.pm.Close(port) { - r.closeLoop(proto, &app.LoopAddr{Port: port, Remote: addr}) // nolint: errcheck + r.closeLoop(appProto, &app.LoopAddr{Port: port, Remote: addr}) // nolint: errcheck } } @@ -323,13 +323,13 @@ func (r *Router) requestLoop(appConn *app.Protocol, raddr *app.Addr) (*app.Addr, NoiseMessage: msg, ExpireAt: time.Now().Add(RouteTTL), Forward: forwardRoute, Reverse: reverseRoute} - proto, tr, err := r.setupProto(context.Background()) + sProto, tr, err := r.setupProto(context.Background()) if err != nil { return nil, err } defer tr.Close() - if err := proto.CreateLoop(l); err != nil { + if err := sProto.CreateLoop(l); err != nil { return nil, fmt.Errorf("route setup: %s", err) } @@ -379,14 +379,14 @@ func (r *Router) closeLoop(appConn *app.Protocol, addr *app.LoopAddr) error { r.Logger.Warnf("Failed to remove loop: %s", err) } - proto, tr, err := r.setupProto(context.Background()) + sProto, tr, err := r.setupProto(context.Background()) if err != nil { return err } defer tr.Close() ld := &setup.LoopData{RemotePK: addr.Remote.PubKey, RemotePort: addr.Remote.Port, LocalPort: addr.Port} - if err := proto.CloseLoop(ld); err != nil { + if err := sProto.CloseLoop(ld); err != nil { return fmt.Errorf("route setup: %s", err) } @@ -426,20 +426,18 @@ func (r *Router) destroyLoop(addr *app.LoopAddr) error { return r.rm.RemoveLoopRule(addr) } -func (r *Router) setupProto(ctx context.Context) (proto *setup.Protocol, tr transport.Transport, err error) { +func (r *Router) setupProto(ctx context.Context) (*setup.Protocol, transport.Transport, error) { if len(r.config.SetupNodes) == 0 { - err = errors.New("route setup: no nodes") - return + return nil, nil, errors.New("route setup: no nodes") } - tr, err = r.tm.CreateTransport(ctx, r.config.SetupNodes[0], "messaging", false) + tr, err := r.tm.CreateTransport(ctx, r.config.SetupNodes[0], "messaging", false) if err != nil { - err = fmt.Errorf("transport: %s", err) - return + return nil, nil, fmt.Errorf("transport: %s", err) } - proto = setup.NewProtocol(tr) - return + sProto := setup.NewSetupProtocol(tr) + return sProto, tr, nil } func (r *Router) fetchBestRoutes(source, destination cipher.PubKey) (routing.Route, routing.Route, error) { diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index c216654fc9..17271778ba 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -302,21 +302,21 @@ func TestRouterSetup(t *testing.T) { tr, err := m2.CreateTransport(context.TODO(), pk1, "mock", false) require.NoError(t, err) - sProto := setup.NewProtocol(tr) + sProto := setup.NewSetupProtocol(tr) rw1, rwIn1 := net.Pipe() go r.ServeApp(rwIn1, 2, &app.Config{}) // nolint: errcheck - proto1 := app.NewProtocol(rw1) + appProto1 := app.NewProtocol(rw1) dataCh := make(chan []byte) - go proto1.Serve(func(_ app.Frame, p []byte) (interface{}, error) { // nolint: errcheck,unparam + go appProto1.Serve(func(_ app.Frame, p []byte) (interface{}, error) { // nolint: errcheck,unparam go func() { dataCh <- p }() return nil, nil }) rw2, rwIn2 := net.Pipe() go r.ServeApp(rwIn2, 4, &app.Config{}) // nolint: errcheck - proto2 := app.NewProtocol(rw2) - go proto2.Serve(func(_ app.Frame, p []byte) (interface{}, error) { // nolint: errcheck,unparam + appProto2 := app.NewProtocol(rw2) + go appProto2.Serve(func(_ app.Frame, p []byte) (interface{}, error) { // nolint: errcheck,unparam go func() { dataCh <- p }() return nil, nil }) @@ -332,7 +332,7 @@ func TestRouterSetup(t *testing.T) { assert.Equal(t, tr.ID, rule.TransportID()) }) - t.Run("confirm loop - responder", func(t *testing.T) { + t.Run("`confirm loop - responder", func(t *testing.T) { confI := noise.Config{ LocalSK: sk2, LocalPK: pk2, @@ -490,8 +490,8 @@ func TestRouterSetupLoop(t *testing.T) { acceptCh, _ := m2.Observe() tr := <-acceptCh - proto := setup.NewProtocol(tr) - p, data, err := proto.ReadPacket() + sProto := setup.NewSetupProtocol(tr) + p, data, err := sProto.ReadPacket() if err != nil { errCh <- err return @@ -513,16 +513,16 @@ func TestRouterSetupLoop(t *testing.T) { return } - errCh <- proto.Respond([]byte{}) + errCh <- sProto.Respond([]byte{}) }() rw, rwIn := net.Pipe() go r.ServeApp(rwIn, 5, &app.Config{}) // nolint: errcheck - proto := app.NewProtocol(rw) - go proto.Serve(nil) // nolint: errcheck + appProto := app.NewProtocol(rw) + go appProto.Serve(nil) // nolint: errcheck addr := &app.Addr{} - require.NoError(t, proto.Send(app.FrameCreateLoop, &app.Addr{PubKey: pk2, Port: 6}, addr)) + require.NoError(t, appProto.Send(app.FrameCreateLoop, &app.Addr{PubKey: pk2, Port: 6}, addr)) require.NoError(t, <-errCh) ll, err := r.pm.GetLoop(10, &app.Addr{PubKey: pk2, Port: 6}) @@ -596,8 +596,8 @@ func TestRouterCloseLoop(t *testing.T) { acceptCh, _ := m2.Observe() tr := <-acceptCh - proto := setup.NewProtocol(tr) - p, data, err := proto.ReadPacket() + sProto := setup.NewSetupProtocol(tr) + p, data, err := sProto.ReadPacket() if err != nil { errCh <- err return @@ -619,7 +619,7 @@ func TestRouterCloseLoop(t *testing.T) { return } - errCh <- proto.Respond([]byte{}) + errCh <- sProto.Respond([]byte{}) }() rw, rwIn := net.Pipe() @@ -684,8 +684,8 @@ func TestRouterCloseLoopOnAppClose(t *testing.T) { acceptCh, _ := m2.Observe() tr := <-acceptCh - proto := setup.NewProtocol(tr) - p, data, err := proto.ReadPacket() + sProto := setup.NewSetupProtocol(tr) + p, data, err := sProto.ReadPacket() if err != nil { errCh <- err return @@ -707,7 +707,7 @@ func TestRouterCloseLoopOnAppClose(t *testing.T) { return } - errCh <- proto.Respond([]byte{}) + errCh <- sProto.Respond([]byte{}) }() rw, rwIn := net.Pipe() @@ -770,8 +770,8 @@ func TestRouterCloseLoopOnRouterClose(t *testing.T) { acceptCh, _ := m2.Observe() tr := <-acceptCh - proto := setup.NewProtocol(tr) - p, data, err := proto.ReadPacket() + sProto := setup.NewSetupProtocol(tr) + p, data, err := sProto.ReadPacket() if err != nil { errCh <- err return @@ -793,13 +793,13 @@ func TestRouterCloseLoopOnRouterClose(t *testing.T) { return } - errCh <- proto.Respond([]byte{}) + errCh <- sProto.Respond([]byte{}) }() rw, rwIn := net.Pipe() go r.ServeApp(rwIn, 5, &app.Config{}) // nolint: errcheck - proto := app.NewProtocol(rw) - go proto.Serve(nil) // nolint: errcheck + appProto := app.NewProtocol(rw) + go appProto.Serve(nil) // nolint: errcheck time.Sleep(100 * time.Millisecond) diff --git a/pkg/setup/protocol.go b/pkg/setup/protocol.go index b3eeeabe13..8ac41863ce 100644 --- a/pkg/setup/protocol.go +++ b/pkg/setup/protocol.go @@ -68,8 +68,8 @@ type Protocol struct { rw io.ReadWriter } -// NewProtocol constructs a new Protocol. -func NewProtocol(rw io.ReadWriter) *Protocol { +// NewSetupProtocol constructs a new setup Protocol. +func NewSetupProtocol(rw io.ReadWriter) *Protocol { return &Protocol{rw} } diff --git a/pkg/setup/setup_protocol_test.go b/pkg/setup/setup_protocol_test.go new file mode 100644 index 0000000000..474e3a2e90 --- /dev/null +++ b/pkg/setup/setup_protocol_test.go @@ -0,0 +1,126 @@ +package setup + +import ( + "fmt" + "net" + + "github.com/skycoin/skywire/pkg/routing" +) + +func ExampleNewSetupProtocol() { + in, _ := net.Pipe() + defer in.Close() + + sProto := NewSetupProtocol(in) + fmt.Printf("Success: %v\n", sProto != nil) + + // Output: Success: true +} + +func Example_sendCmd() { + in, out := net.Pipe() + defer in.Close() + defer out.Close() + inProto, outProto := NewSetupProtocol(in), NewSetupProtocol(out) + + fmt.Printf("Success: %v\n", inProto != nil) + + errCh := make(chan error) + go func(sProto *Protocol) { + frame, err := sProto.readFrame() + if err != nil { + fmt.Println(err.Error()) + } + fmt.Printf("packet: %v, payload: %v\n", Packet(frame[0]), string(frame[1:])) + errCh <- err + }(inProto) + + if err := outProto.sendCMD(PacketCreateLoop, &routing.Loop{}); err != nil { + fmt.Println(err.Error()) + } + + if err := <-errCh; err != nil { + fmt.Println(err.Error()) + } + + // Output: Success: true + // packet: CreateLoop, payload: {"LocalPort":0,"RemotePort":0,"Forward":null,"Reverse":null,"ExpireAt":"0001-01-01T00:00:00Z","NoiseMessage":null} + +} + +func ExampleProtocol_ReadPacket() { + in, out := net.Pipe() + defer in.Close() + defer out.Close() + inProto, outProto := NewSetupProtocol(in), NewSetupProtocol(out) + + fmt.Printf("Success: %v\n", inProto != nil) + + errCh := make(chan error) + go func(sProto *Protocol) { + packet, payload, err := sProto.ReadPacket() + if err != nil { + fmt.Println(err.Error()) + } + + fmt.Printf("packet: %v, payload: %v\n", packet, string(payload)) + errCh <- err + }(inProto) + + if err := outProto.sendCMD(PacketCreateLoop, &routing.Loop{}); err != nil { + fmt.Println(err.Error()) + } + + if err := <-errCh; err != nil { + fmt.Println(err.Error()) + } + + // Output: Success: true + // packet: CreateLoop, payload: {"LocalPort":0,"RemotePort":0,"Forward":null,"Reverse":null,"ExpireAt":"0001-01-01T00:00:00Z","NoiseMessage":null} +} + +func ExampleProtocol_CreateLoop() { + in, out := net.Pipe() + defer in.Close() + defer out.Close() + inProto, outProto := NewSetupProtocol(in), NewSetupProtocol(out) + fmt.Printf("Success: %v\n", inProto != nil) + + // errCh := make(chan error) + go func(sProto *Protocol) { + packet, payload, err := sProto.ReadPacket() + if err != nil { + fmt.Println(err.Error()) + } + + fmt.Printf("packet: %v, payload: %v\n", packet, string(payload)) + + inProto.Respond(nil) + }(inProto) + + // TODO: create non-empty loop + loop := &routing.Loop{} + if err := outProto.CreateLoop(loop); err != nil { + fmt.Println(err.Error()) + } + + // Output: Success: true + // packet: CreateLoop, payload: {"LocalPort":0,"RemotePort":0,"Forward":null,"Reverse":null,"ExpireAt":"0001-01-01T00:00:00Z","NoiseMessage":null} +} + +/* +func ExampleProtocol_ConfirmLoop() { + fmt.Println("TODO") + // Output: Success +} + +func ExampleProtocol_CloseLoop() { + fmt.Println("TODO") + // Output: Success +} + +func ExampleProtocol_LoopClosed() { + fmt.Println("TODO") + // Output: Success +} +*/ diff --git a/pkg/transport-discovery/client/client_test.go b/pkg/transport-discovery/client/client_test.go index a2529961fa..0aba20c20d 100644 --- a/pkg/transport-discovery/client/client_test.go +++ b/pkg/transport-discovery/client/client_test.go @@ -24,7 +24,7 @@ var testPubKey, testSecKey = cipher.GenerateKeyPair() func newTestEntry() *transport.Entry { pk1, _ := cipher.GenerateKeyPair() entry := &transport.Entry{ - ID: transport.MakeTransportID(pk1, testPubKey, "messaging", true), + ID: transport.MakeTransportID(pk1, testPubKey, "messaging", false), Type: "messaging", Public: true, } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index e76e3f0936..d52674fab5 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -82,12 +82,19 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { if errRemote != nil { return nil, errRemote } - if err := validateSignedEntry(sEntry, tr, remote); err != nil { - tm.Logger.Infof("validateSignedEntry: sEntry %v\n tr: %v\n remote: %v\n", sEntry, tr, remote) - tm.Logger.Infof("validateSignedEntry: Edges: %v\n", tr.Edges()) - tm.Logger.Infof("validateSignedEntry: tm.config.PubKey: %v", tm.config.PubKey) - return nil, err - } + + chkRemote := validateSignedEntry(sEntry, tr, remote) + chkLocal := validateSignedEntry(sEntry, tr, tm.Local()) + + tm.Logger.Infof(`validateSignedEntry + chkLocal: %v + chkRemote: %v + sEntry: %v + tr: %v + remote: %v + Edges: %v + tm.config.PubKey: %v + `, chkLocal, chkRemote, sEntry, tr, remote, tr.Edges(), tm.config.PubKey) // Write second signature // sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) @@ -144,5 +151,6 @@ func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { if err != nil { return err } + return cipher.VerifyPubKeySignedPayload(pk, sig, sEntry.Entry.ToBinary()) } diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 4a4abd7ae4..aec3edaa3c 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -272,7 +272,7 @@ func ExampleMakeTransportID() { func ExampleManager_CreateTransport() { // Repetition is required here to guarantee that correctness does not depends on order of edges - for i := 0; i < 256; i++ { + for i := 0; i < 4; i++ { pkB, mgrA, err := MockTransportManager() if err != nil { fmt.Printf("MockTransportManager failed on iteration %v with: %v\n", i, err) From c3b0445c12bfcc8d781d6308d5655cd679620cae Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 8 Apr 2019 11:51:30 +0300 Subject: [PATCH 21/26] Changes: 1. Cleared all unnecessary Infof/Printf statements written in previous commits 2. Manager.ReconnectTransports - there was bug after changing Edges logic 3. Formatted, linted Needed: Tests with setup-node with changes in pkg/transport from this commit --- pkg/app/packet_test.go | 2 +- pkg/manager/user.go | 2 +- pkg/node/node_test.go | 2 +- pkg/setup/setup_protocol_test.go | 4 +++- pkg/transport/handshake.go | 26 +++++++------------------- pkg/transport/handshake_test.go | 2 +- pkg/transport/manager.go | 21 ++++++--------------- pkg/transport/manager_test.go | 20 +++++++++++++------- 8 files changed, 33 insertions(+), 46 deletions(-) diff --git a/pkg/app/packet_test.go b/pkg/app/packet_test.go index d88c71697d..7e7b6f1f8e 100644 --- a/pkg/app/packet_test.go +++ b/pkg/app/packet_test.go @@ -6,7 +6,7 @@ import ( "github.com/skycoin/skywire/pkg/cipher" ) -func Example() { +func ExamplePacket() { pk := cipher.PubKey{} addr := Addr{pk, 0} loopAddr := LoopAddr{0, addr} diff --git a/pkg/manager/user.go b/pkg/manager/user.go index 0ac492c5fc..087fbea7ae 100644 --- a/pkg/manager/user.go +++ b/pkg/manager/user.go @@ -26,7 +26,7 @@ func init() { // User represents a user of the manager. type User struct { Name string - PwSalt []byte/* */ + PwSalt []byte /* */ PwHash cipher.SHA256 } diff --git a/pkg/node/node_test.go b/pkg/node/node_test.go index 5edef3b8e5..40085ce754 100644 --- a/pkg/node/node_test.go +++ b/pkg/node/node_test.go @@ -136,7 +136,7 @@ func TestNodeSpawnAppValidations(t *testing.T) { err string }{ {&AppConfig{App: "chat", Version: "1.0", Port: 2}, "can't bind to reserved port 2"}, - {&AppConfig{App: "chat", Version: "1.0", Port: 10}, "App chat is already started"}, + {&AppConfig{App: "chat", Version: "1.0", Port: 10}, "app chat is already started"}, {&AppConfig{App: "foo", Version: "1.0", Port: 11}, "failed to run app executable: foo"}, } diff --git a/pkg/setup/setup_protocol_test.go b/pkg/setup/setup_protocol_test.go index 474e3a2e90..ba54d3e80e 100644 --- a/pkg/setup/setup_protocol_test.go +++ b/pkg/setup/setup_protocol_test.go @@ -95,7 +95,9 @@ func ExampleProtocol_CreateLoop() { fmt.Printf("packet: %v, payload: %v\n", packet, string(payload)) - inProto.Respond(nil) + if err := inProto.Respond(nil); err != nil { + fmt.Println(err.Error()) + } }(inProto) // TODO: create non-empty loop diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index d52674fab5..9426f4b4b0 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -78,33 +78,21 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } - remote, errRemote := tm.Remote(tr.Edges()) - if errRemote != nil { - return nil, errRemote + remote, err := tm.Remote(tr.Edges()) + if err != nil { + return nil, err + } + + if err := validateSignedEntry(sEntry, tr, remote); err != nil { + return nil, err } - chkRemote := validateSignedEntry(sEntry, tr, remote) - chkLocal := validateSignedEntry(sEntry, tr, tm.Local()) - - tm.Logger.Infof(`validateSignedEntry - chkLocal: %v - chkRemote: %v - sEntry: %v - tr: %v - remote: %v - Edges: %v - tm.config.PubKey: %v - `, chkLocal, chkRemote, sEntry, tr, remote, tr.Edges(), tm.config.PubKey) - - // Write second signature - // sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey) if err := sEntry.Sign(tm.Local(), tm.config.SecKey); err != nil { return nil, err } newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil - var err error if sEntry.Entry.Public { if !newEntry { _, err = tm.config.DiscoveryClient.UpdateStatuses(context.Background(), &Status{ID: sEntry.Entry.ID, IsUp: true}) diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index f9a9e1b76a..b2c604e4dd 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -296,7 +296,7 @@ func TestSettlementHandshakeExistingTransport(t *testing.T) { } -func Example_verifySig() { +func Example_validateSignedEntry() { mockEnv := newHsMockEnv() tm, tr := mockEnv.m1, mockEnv.tr1 diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 378321b0d0..39bf77e204 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -3,7 +3,6 @@ package transport import ( "context" "errors" - "fmt" "math/big" "strings" "sync" @@ -122,15 +121,17 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { entries := tm.entries tm.mu.RUnlock() for _, entry := range entries { - if entry.Edges()[0] != tm.config.PubKey { - continue - } if tm.Transport(entry.ID) != nil { continue } - _, err := tm.createTransport(ctx, entry.Edges()[1], entry.Type, entry.Public) + remote, err := tm.Remote(entry.Edges()) + if err != nil { + tm.Logger.Warnf("Failed to re-establish transport: %s", err) + continue + } + _, err = tm.createTransport(ctx, remote, entry.Type, entry.Public) if err != nil { tm.Logger.Warnf("Failed to re-establish transport: %s", err) continue @@ -349,12 +350,6 @@ func (tm *Manager) createTransport(ctx context.Context, remote cipher.PubKey, tp func (tm *Manager) dialTransport(ctx context.Context, factory Factory, remote cipher.PubKey, public bool) (Transport, *Entry, error) { - fmt.Printf("Manager.dialTransport: %v %v\n", tm.Local(), remote) - - if tm.Local() == remote { - fmt.Println("local and remote are equal. No need to dial") - } - tr, err := factory.Dial(ctx, remote) if err != nil { return nil, nil, err @@ -375,10 +370,6 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } - tm.Logger.Infof("Trying to handshake with: %T %v\n", tr, tr) - tm.Logger.Infof("Handshake from factory: %T %v\n", factory, factory) - tm.Logger.Infof("Handshake: tr.Edges(): %v\n tr.Type(): %v\n", tr.Edges(), tr.Type()) - var handshake settlementHandshake = settlementResponderHandshake entry, err := handshake.Do(tm, tr, 30*time.Second) if err != nil { diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index aec3edaa3c..709af73281 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -119,7 +119,7 @@ func TestTransportManagerReEstablishTransports(t *testing.T) { assert.Equal(t, []string{"mock"}, m1.Factories()) - errCh := make(chan error) + errCh := make(chan error, 2) go func() { errCh <- m1.Serve(context.TODO()) }() @@ -140,22 +140,28 @@ func TestTransportManagerReEstablishTransports(t *testing.T) { require.NoError(t, m2.Close()) - dEntry, err = client.GetTransportByID(context.TODO(), tr2.ID) + dEntry2, err := client.GetTransportByID(context.TODO(), tr2.ID) require.NoError(t, err) - assert.False(t, dEntry.IsUp) + assert.False(t, dEntry2.IsUp) m2, err = NewManager(c2, f2) require.NoError(t, err) - go m2.Serve(context.TODO()) // nolint - time.Sleep(time.Second) + // errCh2 := make(chan error) + go func() { + errCh <- m2.Serve(context.TODO()) // nolint + }() - dEntry, err = client.GetTransportByID(context.TODO(), tr2.ID) + time.Sleep(time.Second) // TODO: this time.Sleep looks fishy - figure out later + dEntry3, err := client.GetTransportByID(context.TODO(), tr2.ID) require.NoError(t, err) - assert.True(t, dEntry.IsUp) + + assert.True(t, dEntry3.IsUp) require.NoError(t, m2.Close()) require.NoError(t, m1.Close()) + + require.NoError(t, <-errCh) require.NoError(t, <-errCh) } From b39ae0c646a1dce8c5f05d9c3199cc4815408d7f Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 8 Apr 2019 15:14:34 +0300 Subject: [PATCH 22/26] Changes: 1. Merged with last mainnet commit 2. Resolved review with Ivan --- pkg/manager/user.go | 2 +- pkg/messaging/client.go | 1 - pkg/transport/handshake.go | 2 -- pkg/transport/manager_test.go | 1 - pkg/transport/tcp_transport_test.go | 2 -- 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pkg/manager/user.go b/pkg/manager/user.go index 087fbea7ae..d0654f27c0 100644 --- a/pkg/manager/user.go +++ b/pkg/manager/user.go @@ -26,7 +26,7 @@ func init() { // User represents a user of the manager. type User struct { Name string - PwSalt []byte /* */ + PwSalt []byte PwHash cipher.SHA256 } diff --git a/pkg/messaging/client.go b/pkg/messaging/client.go index 73278339e8..1abb138044 100644 --- a/pkg/messaging/client.go +++ b/pkg/messaging/client.go @@ -144,7 +144,6 @@ func (c *Client) Accept(ctx context.Context) (transport.Transport, error) { func (c *Client) Dial(ctx context.Context, remote cipher.PubKey) (transport.Transport, error) { entry, err := c.dc.Entry(ctx, remote) if err != nil { - fmt.Printf("Dial with remote = %v\n", remote) return nil, fmt.Errorf("get entry failure: %s", err) } diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 9426f4b4b0..6f175c122c 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -37,8 +37,6 @@ func settlementInitiatorHandshake(public bool) settlementHandshake { Public: public, } - // sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}} - sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { diff --git a/pkg/transport/manager_test.go b/pkg/transport/manager_test.go index 709af73281..e07f545a0c 100644 --- a/pkg/transport/manager_test.go +++ b/pkg/transport/manager_test.go @@ -147,7 +147,6 @@ func TestTransportManagerReEstablishTransports(t *testing.T) { m2, err = NewManager(c2, f2) require.NoError(t, err) - // errCh2 := make(chan error) go func() { errCh <- m2.Serve(context.TODO()) // nolint }() diff --git a/pkg/transport/tcp_transport_test.go b/pkg/transport/tcp_transport_test.go index c83ffd26a4..0715a9c381 100644 --- a/pkg/transport/tcp_transport_test.go +++ b/pkg/transport/tcp_transport_test.go @@ -55,8 +55,6 @@ func TestTCPFactory(t *testing.T) { tr, err := f2.Dial(context.TODO(), pk1) require.NoError(t, err) assert.Equal(t, "tcp", tr.Type()) - // assert.Equal(t, pk2, tr.Local()) - // assert.Equal(t, pk1, tr.Remote()) buf := make([]byte, 3) _, err = tr.Read(buf) From 0055bf76ce25732a77b13a55c9b12c8e7447c74f Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 8 Apr 2019 15:56:09 +0300 Subject: [PATCH 23/26] Changes: 1. Not all Ivan suggestions was resolved in previous commit --- pkg/messaging/client.go | 1 - pkg/router/route_manager.go | 1 - pkg/transport/entry_test.go | 12 +++++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/messaging/client.go b/pkg/messaging/client.go index 1abb138044..d829002176 100644 --- a/pkg/messaging/client.go +++ b/pkg/messaging/client.go @@ -53,7 +53,6 @@ type Config struct { type Client struct { Logger *logging.Logger - // edges [2]cipher.PubKey pubKey cipher.PubKey secKey cipher.SecKey dc client.APIClient diff --git a/pkg/router/route_manager.go b/pkg/router/route_manager.go index 4a0307dfc8..7163690fd7 100644 --- a/pkg/router/route_manager.go +++ b/pkg/router/route_manager.go @@ -77,7 +77,6 @@ func (rm *routeManager) Serve(rw io.ReadWriter) error { proto := setup.NewSetupProtocol(rw) t, body, err := proto.ReadPacket() - fmt.Println("got proto!") if err != nil { fmt.Println("err:", err) return err diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index 76c60d9eab..a42d49303b 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -157,7 +157,17 @@ func ExampleSignedEntry_Signature() { fmt.Printf("SignatureC got error: %v\n", errSigC.Error()) } - errorsPrint(errIdxA, errIdxB, errSigA, errSigB) + doneCh := make(chan bool) + go func(errs ...error) { + for _, err := range errs { + if err != nil { + fmt.Println(err.Error()) + } + } + doneCh <- true + }(errIdxA, errIdxB, errSigA, errSigB) + + <-doneCh // Output: SignatureA got // SignatureB got // SignatureC got error: invalid pubkey From 10cb42439e29e6d07e81c3476b09fa2b94d8cfe4 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Mon, 8 Apr 2019 16:10:39 +0300 Subject: [PATCH 24/26] Changes: 1. Forgot linting. Removed unused code --- pkg/transport/entry_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index a42d49303b..bdbcef376e 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -115,14 +115,6 @@ func ExampleSignedEntry_Sign() { // Both signatures set } -func errorsPrint(errs ...error) { - for _, err := range errs { - if err != nil { - fmt.Println(err.Error()) - } - } -} - func ExampleSignedEntry_Signature() { pkA, skA := cipher.GenerateKeyPair() pkB, skB := cipher.GenerateKeyPair() From 897c788a879c7b44b9cfde97667edbde049bd7a3 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Tue, 9 Apr 2019 08:23:23 +0300 Subject: [PATCH 25/26] Changes: 1. SignedEntry.Index - returns int8, with -1 in case of not found pk in edges 2. SignedEntry.Sign, SignedEntry.Signature now returns bool instead of error 3. Manager.Remote returns bool instead of error 4. Changes in code and test accordingly 5. Linted, formatted --- pkg/messaging/channel.go | 1 + pkg/node/rpc.go | 6 ++-- pkg/router/router.go | 4 +-- pkg/transport/entry.go | 40 +++++++++++++-------------- pkg/transport/entry_test.go | 49 +++++++++++++-------------------- pkg/transport/handshake.go | 39 ++++++++++++++------------ pkg/transport/handshake_test.go | 14 +++++++--- pkg/transport/manager.go | 29 +++++++++---------- pkg/transport/tcp_transport.go | 10 ------- 9 files changed, 91 insertions(+), 101 deletions(-) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index 4a640b8ef2..6d28152178 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -31,6 +31,7 @@ type channel struct { } func (c *channel) Edges() [2]cipher.PubKey { + // Edges returns the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). return transport.SortPubKeys(c.link.Local(), c.remotePK) } diff --git a/pkg/node/rpc.go b/pkg/node/rpc.go index d518d00cb4..b898432c76 100644 --- a/pkg/node/rpc.go +++ b/pkg/node/rpc.go @@ -48,8 +48,8 @@ type TransportSummary struct { } func newTransportSummary(tm *transport.Manager, tp *transport.ManagedTransport, includeLogs bool) *TransportSummary { - remote, err := tm.Remote(tp.Edges()) - if err != nil { + remote, ok := tm.Remote(tp.Edges()) + if !ok { return &TransportSummary{} } @@ -162,7 +162,7 @@ func (r *RPC) Transports(in *TransportsIn, out *[]*TransportSummary) error { return true } r.node.tm.WalkTransports(func(tp *transport.ManagedTransport) bool { - if remote, err := r.node.tm.Remote(tp.Edges()); err == nil { + if remote, ok := r.node.tm.Remote(tp.Edges()); ok { if typeIncluded(tp.Type()) && pkIncluded(r.node.tm.Local(), remote) { *out = append(*out, newTransportSummary(r.node.tm, tp, in.ShowLogs)) } diff --git a/pkg/router/router.go b/pkg/router/router.go index fc15aca05a..2a5c3d5f1e 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -483,8 +483,8 @@ func (r *Router) advanceNoiseHandshake(addr *app.LoopAddr, noiseMsg []byte) (ni func (r *Router) isSetupTransport(tr transport.Transport) bool { for _, pk := range r.config.SetupNodes { - remote, err := r.tm.Remote(tr.Edges()) - if err == nil && remote == pk { + remote, ok := r.tm.Remote(tr.Edges()) + if ok && (remote == pk) { return true } } diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 9d0c6cc2ed..42574de1dc 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -1,7 +1,6 @@ package transport import ( - "errors" "fmt" "strings" @@ -98,41 +97,42 @@ type SignedEntry struct { } // Index returns position of a given pk in edges -func (se *SignedEntry) Index(pk cipher.PubKey) (byte, error) { +func (se *SignedEntry) Index(pk cipher.PubKey) int8 { if pk == se.Entry.Edges()[1] { - return 1, nil + return 1 } if pk == se.Entry.Edges()[0] { - return 0, nil + return 0 } - return 0xff, errors.New("invalid pubkey") + return -1 } // Sign sets Signature for a given PubKey in correct position -func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) error { - idx, err := se.Index(pk) - if err == nil { - se.Signatures[idx] = se.Entry.Signature(secKey) +func (se *SignedEntry) Sign(pk cipher.PubKey, secKey cipher.SecKey) bool { + + idx := se.Index(pk) + if idx == -1 { + return false } - return err + se.Signatures[idx] = se.Entry.Signature(secKey) + + return true } // Signature gets Signature for a given PubKey from correct position -func (se *SignedEntry) Signature(pk cipher.PubKey) (cipher.Sig, error) { - idx, err := se.Index(pk) - if err != nil { - return cipher.Sig{}, err +func (se *SignedEntry) Signature(pk cipher.PubKey) (cipher.Sig, bool) { + idx := se.Index(pk) + if idx == -1 { + return cipher.Sig{}, false } - return se.Signatures[idx], nil + return se.Signatures[idx], true } // NewSignedEntry creates a SignedEntry with first signature -func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) *SignedEntry { +func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) (*SignedEntry, bool) { se := &SignedEntry{Entry: entry} - if err := se.Sign(pk, secKey); err != nil { - return &SignedEntry{} - } - return se + return se, se.Sign(pk, secKey) + } // Status represents the current state of a Transport from the perspective diff --git a/pkg/transport/entry_test.go b/pkg/transport/entry_test.go index bdbcef376e..974dee8153 100644 --- a/pkg/transport/entry_test.go +++ b/pkg/transport/entry_test.go @@ -92,16 +92,16 @@ func ExampleSignedEntry_Sign() { fmt.Println("No signatures set") } - if errA := sEntry.Sign(pkA, skA); errA != nil { - fmt.Println(errA.Error()) + if ok := sEntry.Sign(pkA, skA); !ok { + fmt.Println("error signing with skA") } if (!sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null()) || (!sEntry.Signatures[1].Null() && sEntry.Signatures[0].Null()) { fmt.Println("One signature set") } - if errB := sEntry.Sign(pkB, skB); errB != nil { - fmt.Println(errB.Error()) + if ok := sEntry.Sign(pkB, skB); !ok { + fmt.Println("error signing with skB") } if !sEntry.Signatures[0].Null() && !sEntry.Signatures[1].Null() { @@ -121,45 +121,34 @@ func ExampleSignedEntry_Signature() { entry := NewEntry(pkA, pkB, "mock", true) sEntry := &SignedEntry{Entry: entry} - if errA := sEntry.Sign(pkA, skA); errA != nil { - fmt.Println(errA.Error()) + if ok := sEntry.Sign(pkA, skA); !ok { + fmt.Println("Error signing sEntry with (pkA,skA)") } - if errB := sEntry.Sign(pkB, skB); errB != nil { - fmt.Println(errB.Error()) + if ok := sEntry.Sign(pkB, skB); !ok { + fmt.Println("Error signing sEntry with (pkB,skB)") } - idxA, errIdxA := sEntry.Index(pkA) - idxB, errIdxB := sEntry.Index(pkB) + idxA := sEntry.Index(pkA) + idxB := sEntry.Index(pkB) - sigA, errSigA := sEntry.Signature(pkA) - sigB, errSigB := sEntry.Signature(pkB) + sigA, okA := sEntry.Signature(pkA) + sigB, okB := sEntry.Signature(pkB) - if sigA == sEntry.Signatures[idxA] { + if okA && sigA == sEntry.Signatures[idxA] { fmt.Println("SignatureA got") } - if sigB == sEntry.Signatures[idxB] { + if okB && (sigB == sEntry.Signatures[idxB]) { fmt.Println("SignatureB got") } // Incorrect case pkC, _ := cipher.GenerateKeyPair() - _, errSigC := sEntry.Signature(pkC) - if errSigC != nil { - fmt.Printf("SignatureC got error: %v\n", errSigC.Error()) - } - - doneCh := make(chan bool) - go func(errs ...error) { - for _, err := range errs { - if err != nil { - fmt.Println(err.Error()) - } - } - doneCh <- true - }(errIdxA, errIdxB, errSigA, errSigB) - - <-doneCh + if _, ok := sEntry.Signature(pkC); !ok { + fmt.Printf("SignatureC got error: invalid pubkey") + } + + // // Output: SignatureA got // SignatureB got // SignatureC got error: invalid pubkey diff --git a/pkg/transport/handshake.go b/pkg/transport/handshake.go index 6f175c122c..4a78e87a65 100644 --- a/pkg/transport/handshake.go +++ b/pkg/transport/handshake.go @@ -37,9 +37,11 @@ func settlementInitiatorHandshake(public bool) settlementHandshake { Public: public, } - sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + sEntry, ok := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + if !ok { + return nil, errors.New("error creating signed entry") + } if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { - return nil, fmt.Errorf("settlementInitiatorHandshake NewSignedEntry: %s\n sEntry: %v", err, sEntry) } @@ -47,26 +49,26 @@ func settlementInitiatorHandshake(public bool) settlementHandshake { return nil, fmt.Errorf("write: %s", err) } - rcvdSEntry := &SignedEntry{} - if err := json.NewDecoder(tr).Decode(rcvdSEntry); err != nil { + respSEntry := &SignedEntry{} + if err := json.NewDecoder(tr).Decode(respSEntry); err != nil { return nil, fmt.Errorf("read: %s", err) } // Verifying remote signature - remote, err := tm.Remote(tr.Edges()) - if err != nil { - return nil, err + remote, ok := tm.Remote(tr.Edges()) + if !ok { + return nil, errors.New("configured PubKey not found in edges") } - if err := verifySig(rcvdSEntry, remote); err != nil { + if err := verifySig(respSEntry, remote); err != nil { return nil, err } - newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *rcvdSEntry.Entry }) == nil + newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *respSEntry.Entry }) == nil if newEntry { tm.addEntry(entry) } - return rcvdSEntry.Entry, nil + return respSEntry.Entry, nil } } @@ -76,21 +78,22 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) { return nil, fmt.Errorf("read: %s", err) } - remote, err := tm.Remote(tr.Edges()) - if err != nil { - return nil, err + remote, ok := tm.Remote(tr.Edges()) + if !ok { + return nil, errors.New("configured PubKey not found in edges") } if err := validateSignedEntry(sEntry, tr, remote); err != nil { return nil, err } - if err := sEntry.Sign(tm.Local(), tm.config.SecKey); err != nil { - return nil, err + if ok := sEntry.Sign(tm.Local(), tm.config.SecKey); !ok { + return nil, errors.New("invalid pubkey for signing entry") } newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil + var err error if sEntry.Entry.Public { if !newEntry { _, err = tm.config.DiscoveryClient.UpdateStatuses(context.Background(), &Status{ID: sEntry.Entry.ID, IsUp: true}) @@ -133,9 +136,9 @@ func validateSignedEntry(sEntry *SignedEntry, tr Transport, pk cipher.PubKey) er } func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error { - sig, err := sEntry.Signature(pk) - if err != nil { - return err + sig, ok := sEntry.Signature(pk) + if !ok { + return errors.New("invalid pubkey for retrieving signature") } return cipher.VerifyPubKeySignedPayload(pk, sig, sEntry.Entry.ToBinary()) diff --git a/pkg/transport/handshake_test.go b/pkg/transport/handshake_test.go index b2c604e4dd..0b7fa37ed4 100644 --- a/pkg/transport/handshake_test.go +++ b/pkg/transport/handshake_test.go @@ -103,7 +103,10 @@ func Example_validateEntry() { } entry := NewEntry(pk1, pk2, "mock", true) - sEntry := NewSignedEntry(entry, pk1, sk1) + sEntry, ok := NewSignedEntry(entry, pk1, sk1) + if !ok { + fmt.Println("error creating signed entry") + } if err := validateSignedEntry(sEntry, tr, pk1); err != nil { fmt.Println(err.Error()) } @@ -158,8 +161,8 @@ func TestValidateEntry(t *testing.T) { } sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}} - require.NoError(t, sEntry.Sign(pk1, sk1)) - require.NoError(t, sEntry.Sign(pk2, sk2)) + require.True(t, sEntry.Sign(pk1, sk1)) + require.True(t, sEntry.Sign(pk2, sk2)) require.NoError(t, validateSignedEntry(sEntry, tr, pk1)) } @@ -301,7 +304,10 @@ func Example_validateSignedEntry() { tm, tr := mockEnv.m1, mockEnv.tr1 entry := NewEntry(mockEnv.pk1, mockEnv.pk2, "mock", true) - sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + sEntry, ok := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey) + if !ok { + fmt.Println("error creating signed entry") + } if err := validateSignedEntry(sEntry, tr, tm.config.PubKey); err != nil { fmt.Printf("NewSignedEntry: %v", err.Error()) } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 39bf77e204..6d00fe9b7f 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -126,12 +126,13 @@ func (tm *Manager) ReconnectTransports(ctx context.Context) { continue } - remote, err := tm.Remote(entry.Edges()) - if err != nil { - tm.Logger.Warnf("Failed to re-establish transport: %s", err) + remote, ok := tm.Remote(entry.Edges()) + if !ok { + tm.Logger.Warnf("Failed to re-establish transport: remote pk not found in edges") continue } - _, err = tm.createTransport(ctx, remote, entry.Type, entry.Public) + + _, err := tm.createTransport(ctx, remote, entry.Type, entry.Public) if err != nil { tm.Logger.Warnf("Failed to re-establish transport: %s", err) continue @@ -149,15 +150,15 @@ func (tm *Manager) Local() cipher.PubKey { } // Remote returns the key from the edges that is not equal to Manager.config.PubKey -// in case when both edges are different - returns empty cipher.PubKey{} -func (tm *Manager) Remote(edges [2]cipher.PubKey) (cipher.PubKey, error) { +// in case when both edges are different - returns (cipher.PubKey{}, false) +func (tm *Manager) Remote(edges [2]cipher.PubKey) (cipher.PubKey, bool) { if tm.config.PubKey == edges[0] { - return edges[1], nil + return edges[1], true } if tm.config.PubKey == edges[1] { - return edges[0], nil + return edges[0], true } - return cipher.PubKey{}, errors.New("configured PubKey not found in edges") + return cipher.PubKey{}, false } // CreateDefaultTransports created transports to DefaultNodes if they don't exist. @@ -165,8 +166,8 @@ func (tm *Manager) CreateDefaultTransports(ctx context.Context) { for _, pk := range tm.config.DefaultNodes { exist := false tm.WalkTransports(func(tr *ManagedTransport) bool { - remote, err := tm.Remote(tr.Edges()) - if err == nil && remote == pk { + remote, ok := tm.Remote(tr.Edges()) + if ok && (remote == pk) { exist = true return false } @@ -377,9 +378,9 @@ func (tm *Manager) acceptTransport(ctx context.Context, factory Factory) (*Manag return nil, err } - remote, err := tm.Remote(tr.Edges()) - if err != nil { - return nil, err + remote, ok := tm.Remote(tr.Edges()) + if !ok { + return nil, errors.New("remote pubkey not found in edges") } tm.Logger.Infof("Accepted new transport with type %s from %s. ID: %s", factory.Type(), remote, entry.ID) diff --git a/pkg/transport/tcp_transport.go b/pkg/transport/tcp_transport.go index 19eaa05b2f..dbb363e8fa 100644 --- a/pkg/transport/tcp_transport.go +++ b/pkg/transport/tcp_transport.go @@ -87,16 +87,6 @@ func (tr *TCPTransport) Edges() [2]cipher.PubKey { return SortEdges(tr.edges) } -// // Local returns the local transport edge's public key. -// func (tr *TCPTransport) Local() cipher.PubKey { -// return tr.lpk -// } - -// // Remote returns the remote transport edge's public key. -// func (tr *TCPTransport) Remote() cipher.PubKey { -// return tr.rpk -// } - // Type returns the string representation of the transport type. func (tr *TCPTransport) Type() string { return "tcp" From 0dab9cf6401a86bfcd92c41e1b49f94bfc745784 Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Tue, 9 Apr 2019 11:46:40 +0300 Subject: [PATCH 26/26] Changes: 1. Stylistical changes requested in the last review: removed commented dead code, comments corrected --- pkg/messaging/channel.go | 2 +- pkg/transport/entry.go | 6 +----- pkg/transport/tcp_transport.go | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/pkg/messaging/channel.go b/pkg/messaging/channel.go index 6d28152178..a14a67583f 100644 --- a/pkg/messaging/channel.go +++ b/pkg/messaging/channel.go @@ -30,8 +30,8 @@ type channel struct { noise *noise.Noise } +// Edges returns the public keys of the channel's edge nodes func (c *channel) Edges() [2]cipher.PubKey { - // Edges returns the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). return transport.SortPubKeys(c.link.Local(), c.remotePK) } diff --git a/pkg/transport/entry.go b/pkg/transport/entry.go index 42574de1dc..35313609e6 100644 --- a/pkg/transport/entry.go +++ b/pkg/transport/entry.go @@ -36,12 +36,8 @@ func NewEntry(edgeA, edgeB cipher.PubKey, tpType string, public bool) *Entry { } } -// Edges returns edges of Entry +// Edges returns the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first). func (e *Entry) Edges() [2]cipher.PubKey { - // this sort *must* be needless - // but to remove it: - // - all tests must be passed - // - written Benchmarks return SortPubKeys(e.EdgeKeys[0], e.EdgeKeys[1]) } diff --git a/pkg/transport/tcp_transport.go b/pkg/transport/tcp_transport.go index dbb363e8fa..b2b117e301 100644 --- a/pkg/transport/tcp_transport.go +++ b/pkg/transport/tcp_transport.go @@ -78,8 +78,6 @@ func (f *TCPFactory) Type() string { type TCPTransport struct { *net.TCPConn edges [2]cipher.PubKey - // lpk cipher.PubKey - // rpk cipher.PubKey } // Edges returns the TCPTransport edges.