@@ -25,18 +25,26 @@ import (
25
25
// Funder is a multi-ledger funder.
26
26
type Funder struct {
27
27
funders map [LedgerIDMapKey ]channel.Funder
28
+ egoisticChains map [LedgerIDMapKey ]bool
28
29
}
29
30
30
31
// NewFunder creates a new funder.
31
32
func NewFunder () * Funder {
32
33
return & Funder {
33
34
funders : make (map [LedgerIDMapKey ]channel.Funder ),
35
+ egoisticChains : make (map [LedgerIDMapKey ]bool ),
34
36
}
35
37
}
36
38
37
39
// RegisterFunder registers a funder for a given ledger.
38
40
func (f * Funder ) RegisterFunder (l LedgerID , lf channel.Funder ) {
39
41
f .funders [l .MapKey ()] = lf
42
+ f .egoisticChains [l .MapKey ()] = false
43
+ }
44
+
45
+ // SetEgoisticChain sets the egoistic chain flag for a given ledger.
46
+ func (f * Funder ) SetEgoisticChain (l LedgerID , egoistic bool ) {
47
+ f .egoisticChains [l .MapKey ()] = egoistic
40
48
}
41
49
42
50
// Fund funds a multi-ledger channel. It dispatches funding calls to all
@@ -53,12 +61,25 @@ func (f *Funder) Fund(ctx context.Context, request channel.FundingReq) error {
53
61
return err
54
62
}
55
63
56
- n := len (ledgers )
57
- errs := make (chan error , n )
64
+ var egoisticLedgers []LedgerID
65
+ var nonEgoisticLedgers []LedgerID
66
+
58
67
for _ , l := range ledgers {
59
- go func (l LedgerID ) {
60
- errs <- func () error {
61
- id := l .MapKey ()
68
+ if f .egoisticChains [l .MapKey ()] {
69
+ egoisticLedgers = append (egoisticLedgers , l )
70
+ } else {
71
+ nonEgoisticLedgers = append (nonEgoisticLedgers , l )
72
+ }
73
+ }
74
+
75
+
76
+ // First fund with Funders that are not egoistic.
77
+ nn := len (nonEgoisticLedgers )
78
+ errsN := make (chan error , nn )
79
+ for _ , ln := range nonEgoisticLedgers {
80
+ go func (ln LedgerID ) {
81
+ errsN <- func () error {
82
+ id := ln .MapKey ()
62
83
lf , ok := f .funders [id ]
63
84
if ! ok {
64
85
return fmt .Errorf ("Funder not found for ledger %v" , id )
@@ -67,11 +88,34 @@ func (f *Funder) Fund(ctx context.Context, request channel.FundingReq) error {
67
88
err := lf .Fund (ctx , request )
68
89
return err
69
90
}()
70
- }(l )
91
+ }(ln )
92
+ }
93
+ for i := 0 ; i < nn ; i ++ {
94
+ err := <- errsN
95
+ if err != nil {
96
+ return err
97
+ }
98
+ }
99
+ // Then fund with egoistic Funders.
100
+ ne := len (egoisticLedgers )
101
+ errsE := make (chan error , ne )
102
+ for _ , le := range egoisticLedgers {
103
+ go func (le LedgerID ) {
104
+ errsE <- func () error {
105
+ id := le .MapKey ()
106
+ lf , ok := f .funders [id ]
107
+ if ! ok {
108
+ return fmt .Errorf ("Funder not found for ledger %v" , id )
109
+ }
110
+
111
+ err := lf .Fund (ctx , request )
112
+ return err
113
+ }()
114
+ }(le )
71
115
}
72
116
73
- for i := 0 ; i < n ; i ++ {
74
- err := <- errs
117
+ for i := 0 ; i < ne ; i ++ {
118
+ err := <- errsE
75
119
if err != nil {
76
120
return err
77
121
}
0 commit comments