Skip to content
This repository was archived by the owner on Sep 6, 2022. It is now read-only.

Commit 4744da1

Browse files
thibaultrobertKelvin-MAurélien Gasser
authored
Intermediate model removal (#106)
* Add model hash to compute plan event * Use only one index for inModels * Make sure to ignore final model * Fix key used in ListModelIfIntermediary * Do not wait until compute plan is done * Make sure the hash index is set * Make the clean models optional * Add cleanModels in compute plan output * Concider testtuples before cleaning * Update chaincode/compute_plan.go Co-Authored-By: Aurélien Gasser <aurelien.gasser@owkin.com> * Update chaincode/ledger.go Co-Authored-By: Aurélien Gasser <aurelien.gasser@owkin.com> * Fixes from reviews * Test the clean model function * Rename test function * Update chaincode/input.go Co-Authored-By: Aurélien Gasser <aurelien.gasser@owkin.com> Co-authored-by: Kelvin Moutet <kelvin.moutet@owkin.com> Co-authored-by: Aurélien Gasser <aurelien.gasser@owkin.com>
1 parent 7ea0f49 commit 4744da1

File tree

13 files changed

+196
-58
lines changed

13 files changed

+196
-58
lines changed

EXAMPLES.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ Smart contract: `createComputePlan`
13541354
```
13551355
##### Command peer example:
13561356
```bash
1357-
peer chaincode invoke -n mycc -c '{"Args":["createComputePlan","{\"tag\":\"a tag is simply a string\",\"traintuples\":[{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"aa1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"algoKey\":\"fd1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"id\":\"firstTraintupleID\",\"inModelsIDs\":null,\"tag\":\"\"},{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"aa2bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"algoKey\":\"fd1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"id\":\"secondTraintupleID\",\"inModelsIDs\":[\"firstTraintupleID\"],\"tag\":\"\"}],\"aggregatetuples\":null,\"compositeTraintuples\":null,\"testtuples\":[{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"bb1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"bb2bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"objectiveKey\":\"5c1d9cd1c2c1082dde0921b56d11030c81f62fbb51932758b58ac2569dd0b379\",\"tag\":\"\",\"traintupleID\":\"secondTraintupleID\"}]}"]}' -C myc
1357+
peer chaincode invoke -n mycc -c '{"Args":["createComputePlan","{\"cleanModels\":false,\"tag\":\"a tag is simply a string\",\"traintuples\":[{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"aa1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"algoKey\":\"fd1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"id\":\"firstTraintupleID\",\"inModelsIDs\":null,\"tag\":\"\"},{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"aa2bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"algoKey\":\"fd1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"id\":\"secondTraintupleID\",\"inModelsIDs\":[\"firstTraintupleID\"],\"tag\":\"\"}],\"aggregatetuples\":null,\"compositeTraintuples\":null,\"testtuples\":[{\"dataManagerKey\":\"da1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"dataSampleKeys\":[\"bb1bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\",\"bb2bb7c31f62244c0f3a761cc168804227115793d01c270021fe3f7935482dcc\"],\"objectiveKey\":\"5c1d9cd1c2c1082dde0921b56d11030c81f62fbb51932758b58ac2569dd0b379\",\"tag\":\"\",\"traintupleID\":\"secondTraintupleID\"}]}"]}' -C myc
13581358
```
13591359
##### Command output:
13601360
```json
@@ -1364,6 +1364,7 @@ peer chaincode invoke -n mycc -c '{"Args":["createComputePlan","{\"tag\":\"a tag
13641364
"secondTraintupleID": "d23f8cf290b902417ae698d68e2c6835483521d54fcbece31208517759b7c299"
13651365
},
13661366
"aggregatetupleKeys": null,
1367+
"cleanModels": false,
13671368
"compositeTraintupleKeys": null,
13681369
"computePlanID": "7dd808239c1e062399449bd11b634d9bd1fd0a2b795ad345b62f95b4933bfa17",
13691370
"doneCount": 0,
@@ -1436,6 +1437,7 @@ peer chaincode invoke -n mycc -c '{"Args":["updateComputePlan","{\"computePlanID
14361437
"thirdTraintupleID": "c163663889566a4c51fad3765107774891f8ed456dcc859a9a1a7fcd17b11386"
14371438
},
14381439
"aggregatetupleKeys": null,
1440+
"cleanModels": false,
14391441
"compositeTraintupleKeys": null,
14401442
"computePlanID": "7dd808239c1e062399449bd11b634d9bd1fd0a2b795ad345b62f95b4933bfa17",
14411443
"doneCount": 0,
@@ -1532,6 +1534,7 @@ peer chaincode invoke -n mycc -c '{"Args":["queryComputePlan","{\"key\":\"7dd808
15321534
{
15331535
"IDToKey": {},
15341536
"aggregatetupleKeys": null,
1537+
"cleanModels": false,
15351538
"compositeTraintupleKeys": null,
15361539
"computePlanID": "7dd808239c1e062399449bd11b634d9bd1fd0a2b795ad345b62f95b4933bfa17",
15371540
"doneCount": 0,
@@ -1559,6 +1562,7 @@ peer chaincode invoke -n mycc -c '{"Args":["queryComputePlans"]}' -C myc
15591562
{
15601563
"IDToKey": {},
15611564
"aggregatetupleKeys": null,
1565+
"cleanModels": false,
15621566
"compositeTraintupleKeys": null,
15631567
"computePlanID": "7dd808239c1e062399449bd11b634d9bd1fd0a2b795ad345b62f95b4933bfa17",
15641568
"doneCount": 0,
@@ -1595,6 +1599,7 @@ peer chaincode invoke -n mycc -c '{"Args":["cancelComputePlan","{\"key\":\"7dd80
15951599
{
15961600
"IDToKey": {},
15971601
"aggregatetupleKeys": null,
1602+
"cleanModels": false,
15981603
"compositeTraintupleKeys": null,
15991604
"computePlanID": "7dd808239c1e062399449bd11b634d9bd1fd0a2b795ad345b62f95b4933bfa17",
16001605
"doneCount": 0,

chaincode/compute_plan.go

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func createComputePlan(db *LedgerDB, args []string) (resp outputComputePlan, err
105105
if err != nil {
106106
return
107107
}
108-
return createComputePlanInternal(db, inp.inputComputePlan, inp.Tag)
108+
return createComputePlanInternal(db, inp.inputComputePlan, inp.Tag, inp.CleanModels)
109109
}
110110

111111
func updateComputePlan(db *LedgerDB, args []string) (resp outputComputePlan, err error) {
@@ -125,10 +125,11 @@ func updateComputePlan(db *LedgerDB, args []string) (resp outputComputePlan, err
125125
return updateComputePlanInternal(db, inp.ComputePlanID, inp.inputComputePlan)
126126
}
127127

128-
func createComputePlanInternal(db *LedgerDB, inp inputComputePlan, tag string) (resp outputComputePlan, err error) {
128+
func createComputePlanInternal(db *LedgerDB, inp inputComputePlan, tag string, cleanModels bool) (resp outputComputePlan, err error) {
129129
var computePlan ComputePlan
130130
computePlan.State.Status = StatusWaiting
131131
computePlan.Tag = tag
132+
computePlan.CleanModels = cleanModels
132133
ID, err := computePlan.Create(db)
133134
if err != nil {
134135
return resp, err
@@ -298,7 +299,10 @@ func cancelComputePlan(db *LedgerDB, args []string) (resp outputComputePlan, err
298299
return outputComputePlan{}, err
299300
}
300301

301-
db.AddComputePlanEvent(inp.Key, computeplan.State.Status)
302+
err = db.AddComputePlanEvent(inp.Key, computeplan.State.Status, computeplan.State.IntermediaryModelsInUse)
303+
if err != nil {
304+
return outputComputePlan{}, err
305+
}
302306
resp.Fill(inp.Key, computeplan, []string{})
303307
return resp, nil
304308
}
@@ -404,9 +408,91 @@ func UpdateComputePlanState(db *LedgerDB, ComputePlanID, tupleStatus, tupleKey s
404408
if err != nil {
405409
return err
406410
}
407-
if cp.UpdateStatus(tupleStatus) {
408-
db.AddComputePlanEvent(ComputePlanID, cp.State.Status)
411+
statusUpdated := cp.UpdateStatus(tupleStatus)
412+
doneModels, err := cp.CheckDoneIntermediaryModel(db)
413+
if err != nil {
414+
return err
415+
}
416+
if statusUpdated || len(doneModels) != 0 {
417+
db.AddComputePlanEvent(ComputePlanID, cp.State.Status, doneModels)
409418
return cp.SaveState(db)
410419
}
411420
return nil
412421
}
422+
423+
// TryAddIntermediaryModel will reference the hash model if the compute plan ID
424+
// is not empty and if it's an intermediary model meaning without any children
425+
func TryAddIntermediaryModel(db *LedgerDB, ComputePlanID, tupleKey, modelHash string) error {
426+
if ComputePlanID == "" {
427+
return nil
428+
}
429+
cp, err := db.GetComputePlan(ComputePlanID)
430+
if err != nil {
431+
return err
432+
}
433+
if !cp.CleanModels {
434+
return nil
435+
}
436+
allChildKeys, err := db.GetIndexKeys("tuple~inModel~key", []string{"tuple", tupleKey})
437+
if err != nil {
438+
return err
439+
}
440+
if len(allChildKeys) == 0 {
441+
// If a tuple has no children it's considered final and should not be
442+
// listed in the index
443+
return nil
444+
}
445+
cp.State.IntermediaryModelsInUse = append(cp.State.IntermediaryModelsInUse, modelHash)
446+
447+
return cp.SaveState(db)
448+
}
449+
450+
// CheckDoneIntermediaryModel check all models listed as intermediary. If any of
451+
// them are 'done', meaning that there is no train like tuples or testtuples
452+
// planned to use this model. If that the case its hash will be added to the
453+
// returned slice and remove from the compute plan's one.
454+
func (cp *ComputePlan) CheckDoneIntermediaryModel(db *LedgerDB) ([]string, error) {
455+
if !cp.CleanModels {
456+
return []string{}, nil
457+
}
458+
var doneModels, inUseModels []string
459+
for _, hash := range cp.State.IntermediaryModelsInUse {
460+
done := true
461+
keys, err := db.GetIndexKeys("tuple~modelHash~key", []string{"tuple", hash})
462+
if err != nil {
463+
return []string{}, err
464+
}
465+
if len(keys) == 0 {
466+
// This occurs for the hashes added during the same transaction. But
467+
// thoses models can just be added to the in use ones
468+
inUseModels = append(inUseModels, hash)
469+
continue
470+
}
471+
tupleKey := keys[0]
472+
tupleChildKeys, err := db.GetIndexKeys("tuple~inModel~key", []string{"tuple", tupleKey})
473+
if err != nil {
474+
return []string{}, err
475+
}
476+
testtupleKeys, err := db.GetIndexKeys("testtuple~traintuple~certified~key", []string{"testtuple", tupleKey})
477+
if err != nil {
478+
return []string{}, err
479+
}
480+
allKeys := append(tupleChildKeys, testtupleKeys...)
481+
for _, key := range allKeys {
482+
tuple, err := db.GetGenericTuple(key)
483+
if err != nil {
484+
return []string{}, err
485+
}
486+
if tuple.Status != StatusDone {
487+
inUseModels = append(inUseModels, hash)
488+
done = false
489+
break
490+
}
491+
}
492+
if done {
493+
doneModels = append(doneModels, hash)
494+
}
495+
}
496+
cp.State.IntermediaryModelsInUse = inUseModels
497+
return doneModels, nil
498+
}

chaincode/compute_plan_test.go

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func TestModelCompositionComputePlanWorkflow(t *testing.T) {
162162
mockStub.MockTransactionStart("42")
163163
db := NewLedgerDB(mockStub)
164164

165-
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag)
165+
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag, false)
166166
assert.NoError(t, err)
167167
assert.NotNil(t, db.event)
168168
assert.Len(t, db.event.CompositeTraintuples, 2)
@@ -285,7 +285,7 @@ func TestCreateComputePlanCompositeAggregate(t *testing.T) {
285285
},
286286
}
287287

288-
outCP, err := createComputePlanInternal(db, inCP, tag)
288+
outCP, err := createComputePlanInternal(db, inCP, tag, false)
289289
assert.NoError(t, err)
290290

291291
// Check the composite traintuples
@@ -327,7 +327,7 @@ func TestCreateComputePlan(t *testing.T) {
327327

328328
// Simply test method and return values
329329
inCP := defaultComputePlan
330-
outCP, err := createComputePlanInternal(db, inCP, tag)
330+
outCP, err := createComputePlanInternal(db, inCP, tag, false)
331331
assert.NoError(t, err)
332332
validateDefaultComputePlan(t, outCP)
333333

@@ -380,7 +380,7 @@ func TestQueryComputePlan(t *testing.T) {
380380

381381
// Simply test method and return values
382382
inCP := defaultComputePlan
383-
outCP, err := createComputePlanInternal(db, inCP, tag)
383+
outCP, err := createComputePlanInternal(db, inCP, tag, false)
384384
assert.NoError(t, err)
385385
assert.NotNil(t, outCP)
386386

@@ -400,7 +400,7 @@ func TestQueryComputePlans(t *testing.T) {
400400

401401
// Simply test method and return values
402402
inCP := defaultComputePlan
403-
outCP, err := createComputePlanInternal(db, inCP, tag)
403+
outCP, err := createComputePlanInternal(db, inCP, tag, false)
404404
assert.NoError(t, err)
405405
assert.NotNil(t, outCP)
406406

@@ -448,7 +448,7 @@ func TestComputePlanEmptyTesttuples(t *testing.T) {
448448
Testtuples: []inputComputePlanTesttuple{},
449449
}
450450

451-
outCP, err := createComputePlanInternal(db, inCP, tag)
451+
outCP, err := createComputePlanInternal(db, inCP, tag, false)
452452
assert.NoError(t, err)
453453
assert.NotNil(t, outCP)
454454
assert.Len(t, outCP.TesttupleKeys, 0)
@@ -485,7 +485,7 @@ func TestCancelComputePlan(t *testing.T) {
485485
mockStub.MockTransactionStart("42")
486486
db := NewLedgerDB(mockStub)
487487

488-
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag)
488+
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag, false)
489489
assert.NoError(t, err)
490490
assert.NotNil(t, db.event)
491491
assert.Len(t, db.event.CompositeTraintuples, 2)
@@ -527,7 +527,7 @@ func TestStartedTuplesOfCanceledComputePlan(t *testing.T) {
527527
mockStub.MockTransactionStart("42")
528528
db := NewLedgerDB(mockStub)
529529

530-
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag)
530+
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag, false)
531531
assert.NoError(t, err)
532532

533533
logStartCompositeTrain(db, assetToArgs(inputKey{out.CompositeTraintupleKeys[0]}))
@@ -559,7 +559,7 @@ func TestLogSuccessAfterCancel(t *testing.T) {
559559
mockStub.MockTransactionStart("42")
560560
db := NewLedgerDB(mockStub)
561561

562-
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag)
562+
out, err := createComputePlanInternal(db, modelCompositionComputePlan, tag, false)
563563
assert.NoError(t, err)
564564

565565
logStartCompositeTrain(db, assetToArgs(inputKey{out.CompositeTraintupleKeys[0]}))
@@ -603,7 +603,7 @@ func TestComputePlanMetrics(t *testing.T) {
603603
mockStub.MockTransactionStart("42")
604604
db := NewLedgerDB(mockStub)
605605

606-
out, err := createComputePlanInternal(db, defaultComputePlan, tag)
606+
out, err := createComputePlanInternal(db, defaultComputePlan, tag, false)
607607
assert.NoError(t, err)
608608
checkComputePlanMetrics(t, db, out.ComputePlanID, 0, 3)
609609

@@ -620,6 +620,7 @@ func TestComputePlanMetrics(t *testing.T) {
620620
func traintupleToDone(t *testing.T, db *LedgerDB, key string) {
621621
_, err := logStartTrain(db, assetToArgs(inputKey{Key: key}))
622622
assert.NoError(t, err)
623+
clearEvent(db)
623624

624625
success := inputLogSuccessTrain{}
625626
success.Key = key
@@ -630,6 +631,7 @@ func traintupleToDone(t *testing.T, db *LedgerDB, key string) {
630631
func testtupleToDone(t *testing.T, db *LedgerDB, key string) {
631632
_, err := logStartTest(db, assetToArgs(inputKey{Key: key}))
632633
assert.NoError(t, err)
634+
clearEvent(db)
633635

634636
success := inputLogSuccessTest{}
635637
success.Key = key
@@ -652,7 +654,7 @@ func TestUpdateComputePlan(t *testing.T) {
652654
registerItem(t, *mockStub, "aggregateAlgo")
653655
db := NewLedgerDB(mockStub)
654656

655-
out, err := createComputePlanInternal(db, inputComputePlan{}, tag)
657+
out, err := createComputePlanInternal(db, inputComputePlan{}, tag, false)
656658
assert.NoError(t, err)
657659
assert.Equal(t, tag, out.Tag)
658660

@@ -685,3 +687,48 @@ func TestUpdateComputePlan(t *testing.T) {
685687
"IDToKey should match the newly created tuple keys to its ID")
686688
assert.Equal(t, 4, out.TupleCount)
687689
}
690+
691+
// When the smart contracts are called directly the event object is never reset
692+
// so we need to empty it by hand after each transaction when testing the event content
693+
func clearEvent(db *LedgerDB) {
694+
if db.event == nil {
695+
return
696+
}
697+
*(db.event) = Event{}
698+
}
699+
700+
func TestCleanModels(t *testing.T) {
701+
scc := new(SubstraChaincode)
702+
mockStub := NewMockStubWithRegisterNode("substra", scc)
703+
mockStub.MockTransactionStart("42")
704+
registerItem(t, *mockStub, "aggregateAlgo")
705+
db := NewLedgerDB(mockStub)
706+
707+
out, err := createComputePlanInternal(db, defaultComputePlan, tag, true)
708+
assert.NoError(t, err)
709+
// Just created the compute plan so not in the event
710+
assert.Len(t, db.event.ComputePlans, 0)
711+
clearEvent(db)
712+
713+
traintupleToDone(t, db, out.TraintupleKeys[0])
714+
// Present in the event but without any model to remove
715+
assert.Len(t, db.event.ComputePlans, 1)
716+
assert.Equal(t, db.event.ComputePlans[0].Status, StatusDoing)
717+
assert.Len(t, db.event.ComputePlans[0].ModelsToDelete, 0)
718+
clearEvent(db)
719+
720+
traintupleToDone(t, db, out.TraintupleKeys[1])
721+
// Present in the event but with one intermediary model done to remove
722+
assert.Len(t, db.event.ComputePlans, 1)
723+
assert.Equal(t, db.event.ComputePlans[0].Status, StatusDoing)
724+
assert.Len(t, db.event.ComputePlans[0].ModelsToDelete, 1)
725+
clearEvent(db)
726+
727+
testtupleToDone(t, db, out.TesttupleKeys[0])
728+
// Present in the event but without any model to remove because the last
729+
// model is not intermerdiary
730+
assert.Len(t, db.event.ComputePlans, 1)
731+
assert.Equal(t, db.event.ComputePlans[0].Status, StatusDone)
732+
assert.Len(t, db.event.ComputePlans[0].ModelsToDelete, 0)
733+
734+
}

chaincode/generate_examples_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ func prettyPrintStructElements(buf io.Writer, margin string, strucType reflect.T
349349
continue
350350
case reflect.Bool:
351351
jsonTag := strings.Split(f.Tag.Get("json"), ",")
352-
fmt.Fprintf(buf, "%s\"%s\": %s (%s),\n", margin, jsonTag[0], fieldType, jsonTag[1])
352+
if len(jsonTag) > 1 {
353+
fmt.Fprintf(buf, "%s\"%s\": %s (%s),\n", margin, jsonTag[0], fieldType, jsonTag[1])
354+
}
353355
continue
354356
case reflect.Slice:
355357
if f.Type.Elem().Kind() == reflect.Struct {

chaincode/go.mod

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ require (
66
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
77
github.com/Shopify/sarama v1.22.1 // indirect
88
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
9-
github.com/davecgh/go-spew v1.1.1
109
github.com/docker/go-units v0.4.0 // indirect
1110
github.com/fsouza/go-dockerclient v1.4.0 // indirect
1211
github.com/go-playground/locales v0.12.1 // indirect
@@ -18,7 +17,6 @@ require (
1817
github.com/hashicorp/go-version v1.2.0 // indirect
1918
github.com/hyperledger/fabric v1.4.1
2019
github.com/hyperledger/fabric-amcl v0.0.0-20181230093703-5ccba6eab8d6 // indirect
21-
github.com/karrick/godirwalk v1.15.3 // indirect
2220
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
2321
github.com/kr/pretty v0.1.0 // indirect
2422
github.com/leodido/go-urn v1.1.0 // indirect
@@ -36,8 +34,6 @@ require (
3634
github.com/stretchr/objx v0.2.0 // indirect
3735
github.com/stretchr/testify v1.3.0
3836
github.com/sykesm/zap-logfmt v0.0.2 // indirect
39-
github.com/uudashr/gopkgs v2.0.1+incompatible // indirect
40-
github.com/uudashr/gopkgs/v2 v2.1.2 // indirect
4137
go.uber.org/atomic v1.4.0 // indirect
4238
go.uber.org/zap v1.10.0 // indirect
4339
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f // indirect

chaincode/go.sum

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ github.com/hyperledger/fabric-amcl v0.0.0-20181230093703-5ccba6eab8d6 h1:URjjUy3
8484
github.com/hyperledger/fabric-amcl v0.0.0-20181230093703-5ccba6eab8d6/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE=
8585
github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd h1:anPrsicrIi2ColgWTVPk+TrN42hJIWlfPHSBP9S0ZkM=
8686
github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84=
87-
github.com/karrick/godirwalk v1.12.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
88-
github.com/karrick/godirwalk v1.15.3 h1:0a2pXOgtB16CqIqXTiT7+K9L73f74n/aNQUnH6Ortew=
89-
github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
9087
github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0=
9188
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
9289
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
@@ -166,10 +163,6 @@ github.com/sykesm/zap-logfmt v0.0.2 h1:czSzn+PIXCOAP/4NAIHTTziIKB8201PzoDkKTn+VR
166163
github.com/sykesm/zap-logfmt v0.0.2/go.mod h1:TerDJT124HaO8UTpZ2wJCipJRAKQ9XONM1mzUabIh6M=
167164
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
168165
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
169-
github.com/uudashr/gopkgs v2.0.1+incompatible h1:SuNs9p/XbGcQezR7SguZrZzxqCQozxtd/N8UKBWbWjk=
170-
github.com/uudashr/gopkgs v2.0.1+incompatible/go.mod h1:MtCdKVJkxW7hNKWXPNWfpaeEp8+Ml3Q8myb4yWhn2Hg=
171-
github.com/uudashr/gopkgs/v2 v2.1.2 h1:A0+QH6wqNRHORJnxmqfeuBEsK4nYQ7pgcOHhqpqcrpo=
172-
github.com/uudashr/gopkgs/v2 v2.1.2/go.mod h1:O9VKOuPWrUpVhaxcg7N3QiTrlDhgJb/84Y7b3qaX1rI=
173166
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
174167
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
175168
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=

0 commit comments

Comments
 (0)