github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/accounts/manager.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package accounts 26 27 import ( 28 "reflect" 29 "sort" 30 "sync" 31 32 "github.com/ethereum/go-ethereum/event" 33 ) 34 35 //经理是一个主要的客户经理,可以与 36 //用于签署事务的后端。 37 type Manager struct { 38 backends map[reflect.Type][]Backend //当前注册的后端索引 39 updaters []event.Subscription //所有后端的钱包更新订阅 40 updates chan WalletEvent //后端钱包更改的订阅接收器 41 wallets []Wallet //缓存所有注册后端的所有钱包 42 43 feed event.Feed //钱包信息提示到达/离开 44 45 quit chan chan error 46 lock sync.RWMutex 47 } 48 49 //NewManager创建一个通用的客户经理,通过 50 //支撑的后端。 51 func NewManager(backends ...Backend) *Manager { 52 //从后端检索钱包的初始列表并按URL排序 53 var wallets []Wallet 54 for _, backend := range backends { 55 wallets = merge(wallets, backend.Wallets()...) 56 } 57 //从所有后端订阅钱包通知 58 updates := make(chan WalletEvent, 4*len(backends)) 59 60 subs := make([]event.Subscription, len(backends)) 61 for i, backend := range backends { 62 subs[i] = backend.Subscribe(updates) 63 } 64 //召集客户经理并返回 65 am := &Manager{ 66 backends: make(map[reflect.Type][]Backend), 67 updaters: subs, 68 updates: updates, 69 wallets: wallets, 70 quit: make(chan chan error), 71 } 72 for _, backend := range backends { 73 kind := reflect.TypeOf(backend) 74 am.backends[kind] = append(am.backends[kind], backend) 75 } 76 go am.update() 77 78 return am 79 } 80 81 //关闭将终止客户经理的内部通知进程。 82 func (am *Manager) Close() error { 83 errc := make(chan error) 84 am.quit <- errc 85 return <-errc 86 } 87 88 //更新是钱包事件循环,监听来自后端的通知 89 //更新钱包的缓存。 90 func (am *Manager) update() { 91 //管理器终止时关闭所有订阅 92 defer func() { 93 am.lock.Lock() 94 for _, sub := range am.updaters { 95 sub.Unsubscribe() 96 } 97 am.updaters = nil 98 am.lock.Unlock() 99 }() 100 101 //循环直至终止 102 for { 103 select { 104 case event := <-am.updates: 105 //钱包事件已到达,更新本地缓存 106 am.lock.Lock() 107 switch event.Kind { 108 case WalletArrived: 109 am.wallets = merge(am.wallets, event.Wallet) 110 case WalletDropped: 111 am.wallets = drop(am.wallets, event.Wallet) 112 } 113 am.lock.Unlock() 114 115 //通知事件的任何侦听器 116 am.feed.Send(event) 117 118 case errc := <-am.quit: 119 //经理终止,返回 120 errc <- nil 121 return 122 } 123 } 124 } 125 126 //后端从帐户管理器中检索具有给定类型的后端。 127 func (am *Manager) Backends(kind reflect.Type) []Backend { 128 return am.backends[kind] 129 } 130 131 //钱包将返回在此帐户管理器下注册的所有签名者帐户。 132 func (am *Manager) Wallets() []Wallet { 133 am.lock.RLock() 134 defer am.lock.RUnlock() 135 136 cpy := make([]Wallet, len(am.wallets)) 137 copy(cpy, am.wallets) 138 return cpy 139 } 140 141 //Wallet检索与特定URL关联的钱包。 142 func (am *Manager) Wallet(url string) (Wallet, error) { 143 am.lock.RLock() 144 defer am.lock.RUnlock() 145 146 parsed, err := parseURL(url) 147 if err != nil { 148 return nil, err 149 } 150 for _, wallet := range am.Wallets() { 151 if wallet.URL() == parsed { 152 return wallet, nil 153 } 154 } 155 return nil, ErrUnknownWallet 156 } 157 158 //查找与特定帐户对应的钱包。自从 159 //帐户可以动态地添加到钱包中或从钱包中删除,此方法具有 160 //钱包数量的线性运行时间。 161 func (am *Manager) Find(account Account) (Wallet, error) { 162 am.lock.RLock() 163 defer am.lock.RUnlock() 164 165 for _, wallet := range am.wallets { 166 if wallet.Contains(account) { 167 return wallet, nil 168 } 169 } 170 return nil, ErrUnknownAccount 171 } 172 173 //订阅创建异步订阅以在 174 //经理检测到钱包从其任何后端到达或离开。 175 func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription { 176 return am.feed.Subscribe(sink) 177 } 178 179 //merge是一种类似于append的钱包排序方式,其中 180 //通过在正确位置插入新钱包,可以保留原始列表。 181 // 182 //假定原始切片已按URL排序。 183 func merge(slice []Wallet, wallets ...Wallet) []Wallet { 184 for _, wallet := range wallets { 185 n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) 186 if n == len(slice) { 187 slice = append(slice, wallet) 188 continue 189 } 190 slice = append(slice[:n], append([]Wallet{wallet}, slice[n:]...)...) 191 } 192 return slice 193 } 194 195 //drop是merge的coutterpart,它从排序后的 196 //缓存并删除指定的。 197 func drop(slice []Wallet, wallets ...Wallet) []Wallet { 198 for _, wallet := range wallets { 199 n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) 200 if n == len(slice) { 201 //未找到钱包,可能在启动过程中发生 202 continue 203 } 204 slice = append(slice[:n], slice[n+1:]...) 205 } 206 return slice 207 }