Skip to content

Commit e223208

Browse files
committed
PR feedback
Signed-off-by: hfuss <[email protected]>
1 parent 49b9c8b commit e223208

File tree

12 files changed

+282
-63
lines changed

12 files changed

+282
-63
lines changed

go.work.sum

Lines changed: 202 additions & 6 deletions
Large diffs are not rendered by default.

internal/dataexchange/ffdx/ffdx.go

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,7 @@ func (h *FFDX) beforeConnect(ctx context.Context, w wsclient.WSClient) error {
306306
}
307307

308308
for _, cb := range h.callbacks.handlers {
309-
err := cb.DXConnect(h)
310-
if err != nil {
311-
log.L(ctx).Errorf("error handling DX connect event: %v", err)
312-
}
309+
cb.DXConnect(h)
313310
}
314311

315312
h.initialized = true
@@ -479,51 +476,56 @@ func (h *FFDX) CheckNodeIdentityStatus(ctx context.Context, node *core.Identity)
479476
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
480477
h.metrics.NodeIdentityDXCertMismatch(node.Namespace, mismatchState)
481478
}
479+
log.L(ctx).Debugf("Identity status checked against DX node='%s' mismatch_state='%s'", node.Name, mismatchState)
482480
}()
483481

484482
dxPeer, err := h.GetEndpointInfo(ctx, node.Name) // should be the same as the local node
485483
if err != nil {
486484
return err
487485
}
488486

487+
dxPeerCert := dxPeer.GetString("cert")
489488
// if this occurs, it is either a misconfigured / broken DX or likely a DX that is compatible from an API perspective
490489
// but does not have the same peer info as the HTTPS mTLS DX
491-
if dxPeer.GetString("cert") == "" {
492-
log.L(ctx).Warnf("DX peer does not have a 'cert', DX plugin may be unsupported")
490+
if dxPeerCert == "" {
491+
log.L(ctx).Debugf("DX peer does not have a 'cert', DX plugin may be unsupported")
493492
return nil
494493
}
495494

496-
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
497-
expiry, err := extractSoonestExpiryFromCertBundle(strings.ReplaceAll(dxPeer.GetString("cert"), `\n`, "\n"))
498-
if err == nil {
499-
if expiry.Before(time.Now()) {
500-
log.L(ctx).Warnf("Certificate for node '%s' has expired", node.Name)
501-
}
495+
expiry, err := extractSoonestExpiryFromCertBundle(strings.ReplaceAll(dxPeerCert, `\n`, "\n"))
496+
if err == nil {
497+
if expiry.Before(time.Now()) {
498+
log.L(ctx).Warnf("DX certificate for node '%s' has expired", node.Name)
499+
}
502500

501+
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
503502
h.metrics.NodeIdentityDXCertExpiry(node.Namespace, expiry)
504-
} else {
505-
log.L(ctx).Errorf("Failed to find x509 cert within DX cert bundle node='%s' namespace='%s'", node.Name, node.Namespace)
506503
}
504+
} else {
505+
log.L(ctx).Errorf("Failed to find x509 cert within DX cert bundle node='%s' namespace='%s'", node.Name, node.Namespace)
507506
}
508507

509508
if node.Profile == nil {
510509
return i18n.NewError(ctx, coremsgs.MsgNodeNotProvidedForCheck)
511510
}
512511

513-
if node.Profile.GetString("cert") != "" {
512+
nodeCert := node.Profile.GetString("cert")
513+
if nodeCert != "" {
514514
mismatchState = metrics.NodeIdentityDXCertMismatchStatusHealthy
515-
if dxPeer.GetString("cert") != node.Profile.GetString("cert") {
515+
if dxPeerCert != nodeCert {
516+
log.L(ctx).Warnf("DX certificate for node '%s' is out-of-sync with on-chain identity", node.Name)
516517
mismatchState = metrics.NodeIdentityDXCertMismatchStatusMismatched
517518
}
518519
}
519520

520521
return nil
521522
}
522523

523-
// we assume the cert with the soonest expiry is the leaf cert, but even if its the CA,
524-
// thats what will invalidate the leaf anyways, so really we only care about the soonest expiry
524+
// We assume the cert with the soonest expiry is the leaf cert, but even if its the CA,
525+
// that's what will invalidate the leaf anyways, so really we only care about the soonest expiry.
526+
// So we loop through the bundle finding the soonest expiry, not necessarily the leaf.
525527
func extractSoonestExpiryFromCertBundle(certBundle string) (time.Time, error) {
526-
var leafCert *x509.Certificate
528+
var expiringCert *x509.Certificate
527529
var block *pem.Block
528530
var rest = []byte(certBundle)
529531

@@ -537,16 +539,16 @@ func extractSoonestExpiryFromCertBundle(certBundle string) (time.Time, error) {
537539
if err != nil {
538540
return time.Time{}, fmt.Errorf("failed to parse non-certificate within bundle: %v", err)
539541
}
540-
if leafCert == nil || cert.NotAfter.Before(leafCert.NotAfter) {
541-
leafCert = cert
542+
if expiringCert == nil || cert.NotAfter.Before(expiringCert.NotAfter) {
543+
expiringCert = cert
542544
}
543545
}
544546

545-
if leafCert == nil {
547+
if expiringCert == nil {
546548
return time.Time{}, errors.New("no valid certificate found")
547549
}
548550

549-
return leafCert.NotAfter.UTC(), nil
551+
return expiringCert.NotAfter.UTC(), nil
550552
}
551553

552554
func (h *FFDX) ackLoop() {

internal/dataexchange/ffdx/ffdx_test.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ import (
5252
var utConfig = config.RootSection("ffdx_unit_tests")
5353

5454
const (
55-
// NOTE: the CA cert expires on Monday, February 28, 2035 7:30:57 PM,
56-
// and the leaf cert expires on Monday, February 28, 2028 7:30:57 PM
55+
// NOTE: the CA cert expires on Monday, February 28, 2035 7:30:57 PM UTC,
56+
// and the leaf cert expires on Monday, February 28, 2028 7:30:57 PM UTC
5757
testCertBundle = `
5858
-----BEGIN CERTIFICATE-----
5959
MIIDqTCCApGgAwIBAgIUbZT+Ds4f2oDmGpgVi+SaQq9gxvcwDQYJKoZIhvcNAQEL
@@ -100,6 +100,9 @@ R0gnXX/IZFnLhLh6UpLOBB0KIGENh75EEU7755jMKDKFj16D0uA1Lzrh5YxicTMy
100100
ydFYQLpLycsWl2oV3JB4pO5TIzjY9awkRE0MeMMc
101101
-----END CERTIFICATE-----
102102
`
103+
// The CA is at the bottom of the bundle and expires same as above,
104+
// Monday, February 28, 2035 7:30:57 PM. The leaf cert at the top of
105+
// the bundle is already expired.
103106
testExpiredCert = `
104107
-----BEGIN CERTIFICATE-----
105108
MIIDqjCCApKgAwIBAgIUWnobAQ4vq8gWBAXZBf7XZG3oSicwDQYJKoZIhvcNAQEL
@@ -123,6 +126,28 @@ p/TUQ6q+Mg3W9pSXqLm8jmWNBfDViQF1v9Z3ASFYHUF/yak8jMdBEUpAqDadd/ay
123126
BHm9m8IvFevQjpUw6kyyg77ehEBBn7H/ISTL3HTCpUbkR3qUnFjOyBJ0G02XoozB
124127
I/hI0mpd6y+/JwyvG0smbD2lioiO/JQaUEZGU8pU
125128
-----END CERTIFICATE-----
129+
-----BEGIN CERTIFICATE-----
130+
MIIDqTCCApGgAwIBAgIUbZT+Ds4f2oDmGpgVi+SaQq9gxvcwDQYJKoZIhvcNAQEL
131+
BQAwZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
132+
DVNhbiBGcmFuY2lzY28xEzARBgNVBAoMCkV4YW1wbGUgQ0ExEzARBgNVBAMMCmV4
133+
YW1wbGUtY2EwHhcNMjUwMjI4MTkzMDM4WhcNMzUwMjI2MTkzMDM4WjBkMQswCQYD
134+
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j
135+
aXNjbzETMBEGA1UECgwKRXhhbXBsZSBDQTETMBEGA1UEAwwKZXhhbXBsZS1jYTCC
136+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOWBryFqk0YqQ6pzGJvBDjbV
137+
4BnkMzsv+Fq869Xks09OP4eW44oqfFUmpCFyS3fEmRCz+389t4mKvxcCRIJMW0f5
138+
K9jffG1QKUKL4UuNfEPFpM0MXTwhI+dCdvofdelzc+KBGA6CDYlnWYcCKFSuWeSu
139+
xrb/qCEvhcCaSYt3e2WcRHRuK+OLzM3REeJctC4G/pq858OUV5CZU2B6aGV/9uFL
140+
ZW3TCrOaj+Khzzt5FNvjVdLiUw0FS8VESxFA4kH8p+XUshs9S0e7LfIBSID2NU8+
141+
+5D6HliqNqikbsny1Ps6GhLa+nI37LOVj7nFcG7uk+gb6HUN1+0YvjOJ0/zvnLEC
142+
AwEAAaNTMFEwHQYDVR0OBBYEFJfNoXmIn5S6W7Lcj5G/huW5q1YQMB8GA1UdIwQY
143+
MBaAFJfNoXmIn5S6W7Lcj5G/huW5q1YQMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
144+
hvcNAQELBQADggEBALsdRYJHQMkhjLcrO4Yha1KXh2d+irmi8AqQqQgbLIsSzuqG
145+
bKFiYnJ8PKHaISHlev2xRM9kEjDZ/9q8T4aUELg4eBjj7VK+gs+gSBO6peJ+AcEg
146+
TepsE5GHmhoIIiE/3dIP6XnaM6NBb8q0ewsIg1c5vLlrt8W96LY6Og7f+742VvoV
147+
H31srpGjy7c5nYjBTn/Bu84eb5Lxfvy10sJjnenkXDJvzkUcnfbRzDQ9k5ZuPa05
148+
x+BsxonN0iaeZH91F+Y3kgJidLnU5EhIB/1KXYjuEbl9qUxD6GFHRststPRPeOmj
149+
7C+BtJCIjjavysSqVMvQWLQ6rXms3SpRPAimWqM=
150+
-----END CERTIFICATE-----
126151
`
127152
)
128153

@@ -999,16 +1024,15 @@ type mockDXCallbacks struct {
9991024
connectCalls int
10001025
}
10011026

1002-
func (m *mockDXCallbacks) DXConnect(plugin dataexchange.Plugin) error {
1027+
func (m *mockDXCallbacks) DXConnect(plugin dataexchange.Plugin) {
10031028
m.connectCalls++
1004-
return errors.New("connect callback failed")
10051029
}
10061030

10071031
func (m *mockDXCallbacks) DXEvent(plugin dataexchange.Plugin, event dataexchange.DXEvent) error {
10081032
panic("implement me")
10091033
}
10101034

1011-
func TestWebsocketDXConnectFails(t *testing.T) {
1035+
func TestWebsocketDXConnect(t *testing.T) {
10121036
mockedClient := &http.Client{}
10131037
httpmock.ActivateNonDefault(mockedClient)
10141038
defer httpmock.DeactivateAndReset()

internal/definitions/handler_identity_claim.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func (dh *definitionHandler) handleIdentityClaim(ctx context.Context, state *cor
247247
return dh.database.InsertEvent(ctx, event)
248248
})
249249

250-
if identity.Type == core.IdentityTypeNode {
250+
if dh.multiparty && identity.Type == core.IdentityTypeNode {
251251
nodeDID, err := dh.identity.GetLocalNodeDID(ctx)
252252
if err != nil {
253253
return HandlerResult{Action: core.ActionRetry}, err

internal/definitions/handler_identity_claim_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,6 @@ func TestHandleDefinitionIdentityClaimLocalNodeWithFailingStatusCheck(t *testing
631631
dh.mdx.On("CheckNodeIdentityStatus", ctx, node1).Return(errors.New("failed to check status but no worries"))
632632

633633
dh.multiparty = true
634-
635634
action, err := dh.HandleDefinitionBroadcast(ctx, &bs.BatchState, claimMsg, core.DataArray{claimData}, fftypes.NewUUID())
636635
assert.Equal(t, HandlerResult{Action: core.ActionConfirm}, action)
637636
assert.NoError(t, err)
@@ -669,7 +668,6 @@ func TestHandleDefinitionIdentityClaimLocaNodeMisconfigured(t *testing.T) {
669668
dh.mim.On("GetLocalNodeDID", ctx).Return(node1.DID, errors.New("somehow local node isnt configured but we got this far"))
670669

671670
dh.multiparty = true
672-
673671
action, err := dh.HandleDefinitionBroadcast(ctx, &bs.BatchState, claimMsg, core.DataArray{claimData}, fftypes.NewUUID())
674672
assert.Equal(t, HandlerResult{Action: core.ActionRetry}, action)
675673
assert.Error(t, err)

internal/definitions/handler_identity_update.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func (dh *definitionHandler) handleIdentityUpdate(ctx context.Context, state *co
8888
return dh.database.InsertEvent(ctx, event)
8989
})
9090

91-
if identity.Type == core.IdentityTypeNode {
91+
if dh.multiparty && identity.Type == core.IdentityTypeNode {
9292
nodeDID, err := dh.identity.GetLocalNodeDID(ctx)
9393
if err != nil {
9494
return HandlerResult{Action: core.ActionRetry}, err

internal/definitions/handler_identity_update_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ func TestHandleDefinitionIdentityUpdateLocalNodeOk(t *testing.T) {
293293
dh, bs := newTestDefinitionHandler(t)
294294
ctx := context.Background()
295295

296-
_, node1, updateMsg, updateData, iu := testNodeIdentityUpdate(t)
296+
org1, node1, updateMsg, updateData, iu := testNodeIdentityUpdate(t)
297297

298+
dh.mim.On("VerifyIdentityChain", ctx, node1).Return(org1, false, nil)
298299
dh.mim.On("CachedIdentityLookupByID", ctx, node1.ID).Return(node1, nil)
299300
dh.mdi.On("UpsertIdentity", ctx, mock.MatchedBy(func(identity *core.Identity) bool {
300301
assert.Equal(t, *updateMsg.Header.ID, *identity.Messages.Update)
@@ -308,6 +309,7 @@ func TestHandleDefinitionIdentityUpdateLocalNodeOk(t *testing.T) {
308309
dh.mim.On("GetLocalNodeDID", ctx).Return(node1.DID, nil)
309310
dh.mdx.On("CheckNodeIdentityStatus", ctx, node1).Return(errors.New("failed to check status but no worries"))
310311

312+
dh.multiparty = true
311313
action, err := dh.HandleDefinitionBroadcast(ctx, &bs.BatchState, updateMsg, core.DataArray{updateData}, fftypes.NewUUID())
312314
assert.Equal(t, HandlerResult{Action: core.ActionConfirm}, action)
313315
assert.NoError(t, err)
@@ -320,8 +322,9 @@ func TestHandleDefinitionIdentityUpdateLocalNodeMisconfigured(t *testing.T) {
320322
dh, bs := newTestDefinitionHandler(t)
321323
ctx := context.Background()
322324

323-
_, node1, updateMsg, updateData, iu := testNodeIdentityUpdate(t)
325+
org1, node1, updateMsg, updateData, iu := testNodeIdentityUpdate(t)
324326

327+
dh.mim.On("VerifyIdentityChain", ctx, node1).Return(org1, false, nil)
325328
dh.mim.On("CachedIdentityLookupByID", ctx, node1.ID).Return(node1, nil)
326329
dh.mdi.On("UpsertIdentity", ctx, mock.MatchedBy(func(identity *core.Identity) bool {
327330
assert.Equal(t, *updateMsg.Header.ID, *identity.Messages.Update)
@@ -334,6 +337,7 @@ func TestHandleDefinitionIdentityUpdateLocalNodeMisconfigured(t *testing.T) {
334337
})).Return(nil)
335338
dh.mim.On("GetLocalNodeDID", ctx).Return(node1.DID, errors.New("no local node but somehow we got this far"))
336339

340+
dh.multiparty = true
337341
action, err := dh.HandleDefinitionBroadcast(ctx, &bs.BatchState, updateMsg, core.DataArray{updateData}, fftypes.NewUUID())
338342
assert.Equal(t, HandlerResult{Action: core.ActionRetry}, action)
339343
assert.Error(t, err)

internal/identity/identitymanager.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ func ParseKeyNormalizationConfig(strConfigVal string) int {
104104
}
105105
}
106106

107+
// GetLocalNodeDID returns the expected local node DID based on the multiparty configuration, the node
108+
// identity does not need to be registered yet in order for this to succeed.
107109
func (im *identityManager) GetLocalNodeDID(ctx context.Context) (string, error) {
108110
nodeName := im.multiparty.LocalNode().Name
109111
if nodeName == "" {
@@ -113,6 +115,7 @@ func (im *identityManager) GetLocalNodeDID(ctx context.Context) (string, error)
113115
return fmt.Sprintf("%s%s", core.FireFlyNodeDIDPrefix, nodeName), nil
114116
}
115117

118+
// GetLocalNode returns the local node identity, if it has been registered and is in the DB/cache.
116119
func (im *identityManager) GetLocalNode(ctx context.Context) (node *core.Identity, err error) {
117120
nodeDID, err := im.GetLocalNodeDID(ctx)
118121
if err != nil {

internal/orchestrator/bound_callbacks.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
"sync"
2222

23+
"github.com/hyperledger/firefly-common/pkg/log"
24+
2325
"github.com/hyperledger/firefly-common/pkg/fftypes"
2426
"github.com/hyperledger/firefly-common/pkg/i18n"
2527
"github.com/hyperledger/firefly/internal/coremsgs"
@@ -98,9 +100,12 @@ func (bc *boundCallbacks) TokensApproved(plugin tokens.Plugin, approval *tokens.
98100
return bc.o.events.TokensApproved(plugin, approval)
99101
}
100102

101-
func (bc *boundCallbacks) DXConnect(plugin dataexchange.Plugin) error {
102-
if err := bc.checkStopped(); err != nil {
103-
return err
103+
func (bc *boundCallbacks) DXConnect(plugin dataexchange.Plugin) {
104+
err := bc.checkStopped()
105+
if err == nil {
106+
err = bc.o.networkmap.CheckNodeIdentityStatus(bc.o.ctx)
107+
}
108+
if err != nil {
109+
log.L(bc.o.ctx).Errorf("Error handling DX connect callback: %s", err)
104110
}
105-
return bc.o.networkmap.CheckNodeIdentityStatus(bc.o.ctx)
106111
}

internal/orchestrator/bound_callbacks_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func TestBoundCallbacks(t *testing.T) {
107107
assert.NoError(t, err)
108108

109109
mnm.On("CheckNodeIdentityStatus", mock.Anything, mock.Anything).Return(nil)
110-
err = bc.DXConnect(mdx)
110+
bc.DXConnect(mdx)
111111
assert.NoError(t, err)
112112

113113
mei.On("TokenPoolCreated", mock.Anything, mti, &tokens.TokenPool{}).Return(nil)
@@ -145,8 +145,8 @@ func TestBoundCallbacksStopped(t *testing.T) {
145145
err = bc.DXEvent(nil, &dataexchangemocks.DXEvent{})
146146
assert.Regexp(t, "FF10446", err)
147147

148-
err = bc.DXConnect(nil)
149-
assert.Regexp(t, "FF10446", err)
148+
bc.DXConnect(nil)
149+
// no-op
150150

151151
err = bc.TokenPoolCreated(context.Background(), nil, &tokens.TokenPool{})
152152
assert.Regexp(t, "FF10446", err)

0 commit comments

Comments
 (0)