github.com/klaytn/klaytn@v1.12.1/node/sc/bridge_manager.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package sc 18 19 import ( 20 "context" 21 "errors" 22 "io" 23 "math/big" 24 "path" 25 "sync" 26 "time" 27 28 "github.com/klaytn/klaytn/accounts/abi/bind" 29 "github.com/klaytn/klaytn/blockchain/types" 30 "github.com/klaytn/klaytn/common" 31 bridgecontract "github.com/klaytn/klaytn/contracts/bridge" 32 "github.com/klaytn/klaytn/event" 33 "github.com/klaytn/klaytn/node/sc/bridgepool" 34 "github.com/klaytn/klaytn/rlp" 35 "github.com/klaytn/klaytn/storage/database" 36 ) 37 38 const ( 39 TokenEventChanSize = 10000 40 BridgeAddrJournal = "bridge_addrs.rlp" 41 maxPendingNonceDiff = 1000 // TODO-Klaytn-ServiceChain: update this limitation. Currently, 2 * 500 TPS. 42 43 maxHandledEventSize = 10000000 44 ) 45 46 const ( 47 KLAY uint8 = iota 48 ERC20 49 ERC721 50 ) 51 52 const ( 53 voteTypeValueTransfer = 0 54 voteTypeConfiguration = 1 55 ) 56 57 var ( 58 ErrInvalidTokenPair = errors.New("invalid token pair") 59 ErrNoBridgeInfo = errors.New("bridge information does not exist") 60 ErrDuplicatedBridgeInfo = errors.New("bridge information is duplicated") 61 ErrDuplicatedToken = errors.New("token is duplicated") 62 ErrNoRecovery = errors.New("recovery does not exist") 63 ErrAlreadySubscribed = errors.New("already subscribed") 64 ErrBridgeRestore = errors.New("restoring bridges is failed") 65 ErrBridgeAliasFormatDecode = errors.New("failed to decode alias-format bridge") 66 ) 67 68 var handleVTmethods = map[uint8]string{ 69 KLAY: "handleKLAYTransfer", 70 ERC20: "handleERC20Transfer", 71 ERC721: "handleERC721Transfer", 72 } 73 74 // HandleValueTransferEvent from Bridge contract 75 type HandleValueTransferEvent struct { 76 *bridgecontract.BridgeHandleValueTransfer 77 } 78 79 type BridgeJournal struct { 80 BridgeAlias string `json:"bridgeAlias"` 81 ChildAddress common.Address `json:"childAddress"` 82 ParentAddress common.Address `json:"parentAddress"` 83 Subscribed bool `json:"subscribed"` 84 isLegacyBridgeJournal bool 85 } 86 87 type BridgeInfo struct { 88 subBridge *SubBridge 89 bridgeDB database.DBManager 90 91 counterpartBackend Backend 92 address common.Address 93 counterpartAddress common.Address // TODO-Klaytn need to set counterpart 94 account *accountInfo 95 bridge *bridgecontract.Bridge 96 counterpartBridge *bridgecontract.Bridge 97 onChildChain bool 98 subscribed bool 99 100 counterpartToken map[common.Address]common.Address 101 ctTokenMu sync.RWMutex 102 103 pendingRequestEvent *bridgepool.ItemSortedMap 104 105 isRunning bool 106 handleNonce uint64 // the nonce from the handle value transfer event from the bridge. 107 lowerHandleNonce uint64 // the lower handle nonce from the bridge. 108 requestNonceFromCounterPart uint64 // the nonce from the request value transfer event from the counter part bridge. 109 requestNonce uint64 // the nonce from the request value transfer event from the counter part bridge. 110 111 newEvent chan struct{} 112 closed chan struct{} 113 114 handledEvent *bridgepool.ItemSortedMap 115 } 116 117 type requestEvent struct { 118 nonce uint64 119 } 120 121 func (ev requestEvent) Nonce() uint64 { 122 return ev.nonce 123 } 124 125 func NewBridgeInfo(sb *SubBridge, addr common.Address, bridge *bridgecontract.Bridge, cpAddr common.Address, cpBridge *bridgecontract.Bridge, account *accountInfo, local, subscribed bool, cpBackend Backend) (*BridgeInfo, error) { 126 bi := &BridgeInfo{ 127 subBridge: sb, 128 bridgeDB: sb.chainDB, 129 counterpartBackend: cpBackend, 130 address: addr, 131 counterpartAddress: cpAddr, 132 account: account, 133 bridge: bridge, 134 counterpartBridge: cpBridge, 135 onChildChain: local, 136 subscribed: subscribed, 137 counterpartToken: make(map[common.Address]common.Address), 138 pendingRequestEvent: bridgepool.NewItemSortedMap(bridgepool.UnlimitedItemSortedMap), 139 isRunning: true, 140 handleNonce: 0, 141 lowerHandleNonce: 0, 142 requestNonceFromCounterPart: 0, 143 requestNonce: 0, 144 newEvent: make(chan struct{}), 145 closed: make(chan struct{}), 146 handledEvent: bridgepool.NewItemSortedMap(maxHandledEventSize), 147 } 148 149 if err := bi.UpdateInfo(); err != nil { 150 return bi, err 151 } 152 153 go bi.loop() 154 155 return bi, nil 156 } 157 158 // handleValueTransferLog records value transfer transaction's log 159 func handleValueTransferLog(onChild bool, funcName, txHash string, reqNonce uint64, from, to common.Address, valueOrTokenId *big.Int) { 160 // Note the `onChild` should be interpreted as reverse. Refer `ProcessRequestEvent()` in sub_event_handler.go 161 var vtDir string 162 if onChild { 163 vtDir = "(parent--->child)" 164 } else { 165 vtDir = "(child--->parent)" 166 } 167 logger.Trace("Bridge contract transaction is created", "VTDirection", vtDir, 168 "contractCall", funcName, "nonce", reqNonce, "txHash", txHash, "from", from, "to", to, "valueOrTokenID", valueOrTokenId) 169 } 170 171 func (bi *BridgeInfo) loop() { 172 ticker := time.NewTicker(time.Second) 173 defer ticker.Stop() 174 175 logger.Info("start bridge loop", "addr", bi.address.String(), "onChildChain", bi.onChildChain) 176 177 for { 178 select { 179 case <-bi.newEvent: 180 bi.processingPendingRequestEvents() 181 182 case <-ticker.C: 183 bi.processingPendingRequestEvents() 184 185 case <-bi.closed: 186 logger.Info("stop bridge loop", "addr", bi.address.String(), "onChildChain", bi.onChildChain) 187 return 188 } 189 } 190 } 191 192 func (bi *BridgeInfo) RegisterToken(token, counterpartToken common.Address) error { 193 bi.ctTokenMu.Lock() 194 defer bi.ctTokenMu.Unlock() 195 196 _, exist := bi.counterpartToken[token] 197 if exist { 198 return ErrDuplicatedToken 199 } 200 bi.counterpartToken[token] = counterpartToken 201 return nil 202 } 203 204 func (bi *BridgeInfo) DeregisterToken(token, counterpartToken common.Address) error { 205 bi.ctTokenMu.Lock() 206 defer bi.ctTokenMu.Unlock() 207 208 _, exist := bi.counterpartToken[token] 209 if !exist { 210 return ErrInvalidTokenPair 211 } 212 delete(bi.counterpartToken, token) 213 return nil 214 } 215 216 func (bi *BridgeInfo) GetCounterPartToken(token common.Address) common.Address { 217 bi.ctTokenMu.RLock() 218 defer bi.ctTokenMu.RUnlock() 219 220 cpToken, exist := bi.counterpartToken[token] 221 if !exist { 222 return common.Address{} 223 } 224 return cpToken 225 } 226 227 func (bi *BridgeInfo) GetPendingRequestEvents() []IRequestValueTransferEvent { 228 ready := bi.pendingRequestEvent.Pop(maxPendingNonceDiff / 2) 229 readyEvent := make([]IRequestValueTransferEvent, len(ready)) 230 for i, item := range ready { 231 readyEvent[i] = item.(IRequestValueTransferEvent) 232 } 233 vtPendingRequestEventCounter.Dec((int64)(len(ready))) 234 return readyEvent 235 } 236 237 // processingPendingRequestEvents handles pending request value transfer events of the bridge. 238 func (bi *BridgeInfo) processingPendingRequestEvents() { 239 ReadyEvent := bi.GetReadyRequestValueTransferEvents() 240 if ReadyEvent == nil { 241 return 242 } 243 244 logger.Trace("Get ready request value transfer event", "len(readyEvent)", len(ReadyEvent), "len(pendingEvent)", bi.pendingRequestEvent.Len()) 245 246 for idx, ev := range ReadyEvent { 247 if ev.GetRequestNonce() < bi.lowerHandleNonce || bi.handledEvent.Exist(ev.GetRequestNonce()) { 248 logger.Trace("handled requests can be ignored", "RequestNonce", ev.GetRequestNonce(), "lowerHandleNonce", bi.lowerHandleNonce) 249 continue 250 } 251 252 if err := bi.handleRequestValueTransferEvent(ev); err != nil { 253 bi.AddRequestValueTransferEvents(ReadyEvent[idx:]) 254 logger.Error("Failed handle request value transfer event", "err", err, "len(RePutEvent)", len(ReadyEvent[idx:])) 255 return 256 } 257 } 258 } 259 260 func (bi *BridgeInfo) UpdateInfo() error { 261 if bi == nil { 262 return ErrNoBridgeInfo 263 } 264 265 rn, err := bi.bridge.RequestNonce(nil) 266 if err != nil { 267 return err 268 } 269 bi.SetRequestNonce(rn) 270 271 hn, err := bi.bridge.LowerHandleNonce(nil) 272 if err != nil { 273 return err 274 } 275 276 bi.lowerHandleNonce = hn 277 278 bi.SetHandleNonce(hn) 279 bi.SetRequestNonceFromCounterpart(hn) 280 281 isRunning, err := bi.bridge.IsRunning(nil) 282 if err != nil { 283 return err 284 } 285 bi.isRunning = isRunning 286 287 return nil 288 } 289 290 // handleRequestValueTransferEvent handles the given request value transfer event. 291 func (bi *BridgeInfo) handleRequestValueTransferEvent(ev IRequestValueTransferEvent) error { 292 var ( 293 tokenType = ev.GetTokenType() 294 tokenAddr, from, to, contractAddr = ev.GetTokenAddress(), ev.GetFrom(), ev.GetTo(), ev.GetRaw().Address 295 txHash = ev.GetRaw().TxHash 296 valueOrTokenId = ev.GetValueOrTokenId() 297 requestNonce, blkNumber = ev.GetRequestNonce(), ev.GetRaw().BlockNumber 298 extraData = ev.GetExtraData() 299 ) 300 301 ctpartTokenAddr := bi.GetCounterPartToken(tokenAddr) 302 // TODO-Klaytn-Servicechain Add counterpart token address in requestValueTransferEvent 303 if tokenType != KLAY && ctpartTokenAddr == (common.Address{}) { 304 logger.Warn("Unregistered counter part token address.", "addr", ctpartTokenAddr.Hex()) 305 ctTokenAddr, err := bi.counterpartBridge.RegisteredTokens(nil, tokenAddr) 306 if err != nil { 307 return err 308 } 309 if ctTokenAddr == (common.Address{}) { 310 return errors.New("can't get counterpart token from bridge") 311 } 312 if err := bi.RegisterToken(tokenAddr, ctTokenAddr); err != nil { 313 return err 314 } 315 ctpartTokenAddr = ctTokenAddr 316 logger.Info("Register counter part token address.", "addr", ctpartTokenAddr.Hex(), "cpAddr", ctTokenAddr.Hex()) 317 } 318 319 bridgeAcc := bi.account 320 321 bridgeAcc.Lock() 322 defer bridgeAcc.UnLock() 323 324 auth := bridgeAcc.GenerateTransactOpts() 325 326 var handleTx *types.Transaction 327 var err error 328 329 switch tokenType { 330 case KLAY: 331 handleTx, err = bi.bridge.HandleKLAYTransfer(auth, txHash, from, to, valueOrTokenId, requestNonce, blkNumber, extraData) 332 if err != nil { 333 return err 334 } 335 handleValueTransferLog(bi.onChildChain, handleVTmethods[KLAY], handleTx.Hash().String(), requestNonce, from, to, valueOrTokenId) 336 case ERC20: 337 handleTx, err = bi.bridge.HandleERC20Transfer(auth, txHash, from, to, ctpartTokenAddr, valueOrTokenId, requestNonce, blkNumber, extraData) 338 if err != nil { 339 return err 340 } 341 handleValueTransferLog(bi.onChildChain, handleVTmethods[ERC20], handleTx.Hash().String(), requestNonce, from, to, valueOrTokenId) 342 case ERC721: 343 uri := GetURI(ev) 344 handleTx, err = bi.bridge.HandleERC721Transfer(auth, txHash, from, to, ctpartTokenAddr, valueOrTokenId, requestNonce, blkNumber, uri, extraData) 345 if err != nil { 346 return err 347 } 348 handleValueTransferLog(bi.onChildChain, handleVTmethods[ERC721], handleTx.Hash().String(), requestNonce, from, to, valueOrTokenId) 349 default: 350 logger.Error("Got Unknown Token Type ReceivedEvent", "bridge", contractAddr, "nonce", requestNonce, "from", from) 351 return nil 352 } 353 354 bridgeAcc.IncNonce() 355 356 bi.bridgeDB.WriteHandleTxHashFromRequestTxHash(txHash, handleTx.Hash()) 357 return nil 358 } 359 360 // SetRequestNonceFromCounterpart sets the request nonce from counterpart bridge. 361 func (bi *BridgeInfo) SetRequestNonceFromCounterpart(nonce uint64) { 362 if bi.requestNonceFromCounterPart < nonce { 363 vtRequestNonceCount.Inc(int64(nonce - bi.requestNonceFromCounterPart)) 364 bi.requestNonceFromCounterPart = nonce 365 } 366 } 367 368 // SetRequestNonce sets the request nonce of the bridge. 369 func (bi *BridgeInfo) SetRequestNonce(nonce uint64) { 370 if bi.requestNonce < nonce { 371 bi.requestNonce = nonce 372 } 373 } 374 375 // MarkHandledNonce marks the handled nonce and sets the handle nonce value. 376 func (bi *BridgeInfo) MarkHandledNonce(nonce uint64) { 377 bi.SetHandleNonce(nonce + 1) 378 bi.handledEvent.Put(requestEvent{nonce}) 379 } 380 381 // SetHandleNonce sets the handled nonce with a new nonce. 382 func (bi *BridgeInfo) SetHandleNonce(nonce uint64) { 383 if bi.handleNonce < nonce { 384 vtHandleNonceCount.Inc(int64(nonce - bi.handleNonce)) 385 bi.handleNonce = nonce 386 } 387 } 388 389 // UpdateLowerHandleNonce updates the lower handle nonce. 390 func (bi *BridgeInfo) UpdateLowerHandleNonce(nonce uint64) { 391 if bi.lowerHandleNonce < nonce { 392 vtLowerHandleNonceCount.Inc(int64(nonce - bi.lowerHandleNonce)) 393 bi.lowerHandleNonce = nonce 394 395 bi.handledEvent.Forward(nonce) 396 } 397 } 398 399 // AddRequestValueTransferEvents adds events into the pendingRequestEvent. 400 func (bi *BridgeInfo) AddRequestValueTransferEvents(evs []IRequestValueTransferEvent) { 401 for _, ev := range evs { 402 if bi.pendingRequestEvent.Len() > maxPendingNonceDiff { 403 flatten := bi.pendingRequestEvent.Flatten() 404 maxNonce := flatten[len(flatten)-1].Nonce() 405 if ev.Nonce() >= maxNonce || bi.pendingRequestEvent.Exist(ev.Nonce()) { 406 continue 407 } 408 bi.pendingRequestEvent.Remove(maxNonce) 409 vtPendingRequestEventCounter.Dec(1) 410 logger.Trace("List is full but add requestValueTransfer ", "newNonce", ev.Nonce(), "removedNonce", maxNonce) 411 } 412 413 bi.SetRequestNonceFromCounterpart(ev.GetRequestNonce() + 1) 414 bi.pendingRequestEvent.Put(ev) 415 vtPendingRequestEventCounter.Inc(1) 416 } 417 logger.Trace("added pending request events to the bridge info:", "bi.pendingRequestEvent", bi.pendingRequestEvent.Len()) 418 419 select { 420 case bi.newEvent <- struct{}{}: 421 default: 422 } 423 } 424 425 // GetReadyRequestValueTransferEvents returns the processable events with the increasing nonce. 426 func (bi *BridgeInfo) GetReadyRequestValueTransferEvents() []IRequestValueTransferEvent { 427 return bi.GetPendingRequestEvents() 428 } 429 430 // GetCurrentBlockNumber returns a current block number for each local and remote backend. 431 func (bi *BridgeInfo) GetCurrentBlockNumber() (uint64, error) { 432 if bi.onChildChain { 433 ctx, cancel := context.WithTimeout(context.Background(), timeout) 434 defer cancel() 435 return bi.subBridge.localBackend.CurrentBlockNumber(ctx) 436 } 437 return bi.subBridge.remoteBackend.CurrentBlockNumber(context.Background()) 438 } 439 440 // DecodeRLP decodes the Klaytn 441 func (b *BridgeJournal) DecodeRLP(s *rlp.Stream) error { 442 var LegacyBridgeAddrInfo struct { 443 LocalAddress common.Address 444 RemoteAddress common.Address 445 Paired bool 446 } 447 var BridgeAddrInfo struct { 448 BridgeAlias string 449 LocalAddress common.Address 450 RemoteAddress common.Address 451 Paired bool 452 } 453 if !b.isLegacyBridgeJournal { 454 if err := s.Decode(&BridgeAddrInfo); err != nil { 455 logger.Trace("Failed to decode. Try decode again with legacy structure") 456 b.isLegacyBridgeJournal = true 457 if err == io.EOF { 458 return err 459 } 460 return ErrBridgeAliasFormatDecode 461 } 462 b.BridgeAlias, b.ChildAddress, b.ParentAddress, b.Subscribed = BridgeAddrInfo.BridgeAlias, BridgeAddrInfo.LocalAddress, BridgeAddrInfo.RemoteAddress, BridgeAddrInfo.Paired 463 } else { 464 if err := s.Decode(&LegacyBridgeAddrInfo); err != nil { 465 return err 466 } 467 b.BridgeAlias, b.ChildAddress, b.ParentAddress, b.Subscribed = "", LegacyBridgeAddrInfo.LocalAddress, LegacyBridgeAddrInfo.RemoteAddress, LegacyBridgeAddrInfo.Paired 468 } 469 return nil 470 } 471 472 // EncodeRLP serializes a BridgeJournal into the Klaytn RLP BridgeJournal format. 473 func (b *BridgeJournal) EncodeRLP(w io.Writer) error { 474 return rlp.Encode(w, []interface{}{ 475 b.BridgeAlias, 476 b.ChildAddress, 477 b.ParentAddress, 478 b.Subscribed, 479 }) 480 } 481 482 // BridgeManager manages Bridge SmartContracts 483 // for value transfer between child chain and parent chain 484 type BridgeManager struct { 485 subBridge *SubBridge 486 487 receivedEvents map[common.Address][]event.Subscription 488 withdrawEvents map[common.Address]event.Subscription 489 bridges map[common.Address]*BridgeInfo 490 bridgesMu sync.RWMutex 491 tokenEventMu sync.RWMutex 492 493 reqVTevFeeder event.Feed 494 reqVTevEncodedFeeder event.Feed 495 handleEventFeeder event.Feed 496 497 scope event.SubscriptionScope 498 499 journal *bridgeAddrJournal 500 recoveries map[common.Address]*valueTransferRecovery 501 auth *bind.TransactOpts 502 } 503 504 func NewBridgeManager(main *SubBridge) (*BridgeManager, error) { 505 bridgeAddrJournal := newBridgeAddrJournal(path.Join(main.config.DataDir, BridgeAddrJournal)) 506 507 bridgeManager := &BridgeManager{ 508 subBridge: main, 509 receivedEvents: make(map[common.Address][]event.Subscription), 510 withdrawEvents: make(map[common.Address]event.Subscription), 511 bridges: make(map[common.Address]*BridgeInfo), 512 journal: bridgeAddrJournal, 513 recoveries: make(map[common.Address]*valueTransferRecovery), 514 } 515 516 logger.Info("Load Bridge Address from JournalFiles ", "path", bridgeManager.journal.path) 517 bridgeManager.journal.cacheMu.Lock() 518 519 bridgeManager.journal.cache = make(map[common.Address]*BridgeJournal) 520 bridgeManager.journal.aliasCache = make(map[string]common.Address) 521 522 if err := bridgeManager.journal.load(func(gwjournal BridgeJournal) error { 523 logger.Info("Load Bridge Address from JournalFiles ", 524 "alias", gwjournal.BridgeAlias, 525 "local address", gwjournal.ChildAddress.Hex(), 526 "remote address", gwjournal.ParentAddress.Hex()) 527 bridgeManager.journal.cache[gwjournal.ChildAddress] = &gwjournal 528 bridgeManager.journal.aliasCache[gwjournal.BridgeAlias] = gwjournal.ChildAddress 529 return nil 530 }); err != nil { 531 logger.Error("fail to load bridge address", "err", err) 532 } 533 534 bridgeManager.journal.cacheMu.Unlock() 535 536 if err := bridgeManager.journal.rotate(bridgeManager.GetAllBridge()); err != nil { 537 logger.Error("fail to rotate bridge journal", "err", err) 538 } 539 540 return bridgeManager, nil 541 } 542 543 func (bm *BridgeManager) IsValidBridgePair(bridge1, bridge2 common.Address) bool { 544 b1, ok1 := bm.GetBridgeInfo(bridge1) 545 b2, ok2 := bm.GetBridgeInfo(bridge2) 546 if !ok1 || !ok2 { 547 return false 548 } 549 return bridge1 == b2.counterpartAddress && bridge2 == b1.counterpartAddress 550 } 551 552 func (bm *BridgeManager) GetCounterPartBridgeAddr(bridgeAddr common.Address) common.Address { 553 bridge, ok := bm.GetBridgeInfo(bridgeAddr) 554 if ok { 555 return bridge.counterpartAddress 556 } 557 return common.Address{} 558 } 559 560 func (bm *BridgeManager) GetCounterPartBridge(bridgeAddr common.Address) *bridgecontract.Bridge { 561 bridge, ok := bm.GetBridgeInfo(bridgeAddr) 562 if ok { 563 return bridge.counterpartBridge 564 } 565 return nil 566 } 567 568 // LogBridgeStatus logs the bridge contract requested/handled nonce status as an information. 569 func (bm *BridgeManager) LogBridgeStatus() { 570 bm.bridgesMu.RLock() 571 defer bm.bridgesMu.RUnlock() 572 573 if len(bm.bridges) == 0 { 574 return 575 } 576 577 var p2cTotalRequestNonce, p2cTotalHandleNonce, p2cTotalLowerHandleNonce uint64 578 var c2pTotalRequestNonce, c2pTotalHandleNonce, c2pTotalLowerHandleNonce uint64 579 580 for bAddr, b := range bm.bridges { 581 diffNonce := b.requestNonceFromCounterPart - b.handleNonce 582 583 if b.subscribed { 584 var headStr string 585 if b.onChildChain { 586 headStr = "Bridge(Parent -> Child Chain)" 587 p2cTotalRequestNonce += b.requestNonceFromCounterPart 588 p2cTotalHandleNonce += b.handleNonce 589 p2cTotalLowerHandleNonce += b.lowerHandleNonce 590 } else { 591 headStr = "Bridge(Child -> Parent Chain)" 592 c2pTotalRequestNonce += b.requestNonceFromCounterPart 593 c2pTotalHandleNonce += b.handleNonce 594 c2pTotalLowerHandleNonce += b.lowerHandleNonce 595 } 596 logger.Debug(headStr, "bridge", bAddr.String(), "requestNonce", b.requestNonceFromCounterPart, "lowerHandleNonce", b.lowerHandleNonce, "handleNonce", b.handleNonce, "pending", diffNonce) 597 } 598 } 599 600 logger.Info("VT : Parent -> Child Chain", "request", p2cTotalRequestNonce, "handle", p2cTotalHandleNonce, "lowerHandle", p2cTotalLowerHandleNonce, "pending", p2cTotalRequestNonce-p2cTotalLowerHandleNonce) 601 logger.Info("VT : Child -> Parent Chain", "request", c2pTotalRequestNonce, "handle", c2pTotalHandleNonce, "lowerHandle", c2pTotalLowerHandleNonce, "pending", c2pTotalRequestNonce-c2pTotalLowerHandleNonce) 602 } 603 604 // SubscribeReqVTev registers a subscription of RequestValueTransferEvent. 605 func (bm *BridgeManager) SubscribeReqVTev(ch chan<- RequestValueTransferEvent) event.Subscription { 606 return bm.scope.Track(bm.reqVTevFeeder.Subscribe(ch)) 607 } 608 609 // SubscribeReqVTencodedEv registers a subscription of RequestValueTransferEncoded. 610 func (bm *BridgeManager) SubscribeReqVTencodedEv(ch chan<- RequestValueTransferEncodedEvent) event.Subscription { 611 return bm.scope.Track(bm.reqVTevEncodedFeeder.Subscribe(ch)) 612 } 613 614 // SubscribeHandleVTev registers a subscription of HandleValueTransferEvent. 615 func (bm *BridgeManager) SubscribeHandleVTev(ch chan<- *HandleValueTransferEvent) event.Subscription { 616 return bm.scope.Track(bm.handleEventFeeder.Subscribe(ch)) 617 } 618 619 // getAddrByAlias returns a pair of child bridge address and parent bridge address 620 func (bm *BridgeManager) getAddrByAlias(bridgeAlias string) (common.Address, common.Address, error) { 621 bm.journal.cacheMu.RLock() 622 defer bm.journal.cacheMu.RUnlock() 623 624 journalAddr, ok := bm.journal.aliasCache[bridgeAlias] 625 if !ok { 626 return common.Address{}, common.Address{}, ErrEmptyBridgeAlias 627 } 628 journal, ok := bm.journal.cache[journalAddr] 629 if !ok { 630 return common.Address{}, common.Address{}, ErrEmptyJournalCache 631 } 632 return journal.ChildAddress, journal.ParentAddress, nil 633 } 634 635 // GetBridge returns bridge journal structure that contains local(child) and remote(parent) addresses. 636 func (bm *BridgeManager) GetBridge(bridgeAlias string) *BridgeJournal { 637 bm.journal.cacheMu.RLock() 638 defer bm.journal.cacheMu.RUnlock() 639 640 return bm.journal.cache[bm.journal.aliasCache[bridgeAlias]] 641 } 642 643 // GetAllBridge returns a slice of journal cache. 644 func (bm *BridgeManager) GetAllBridge() []*BridgeJournal { 645 bm.journal.cacheMu.RLock() 646 defer bm.journal.cacheMu.RUnlock() 647 648 gwjs := make([]*BridgeJournal, 0) 649 for _, journal := range bm.journal.cache { 650 gwjs = append(gwjs, journal) 651 } 652 return gwjs 653 } 654 655 // GetBridgeInfo returns bridge contract of the specified address. 656 func (bm *BridgeManager) GetBridgeInfo(addr common.Address) (*BridgeInfo, bool) { 657 bm.bridgesMu.RLock() 658 defer bm.bridgesMu.RUnlock() 659 660 bridge, ok := bm.bridges[addr] 661 return bridge, ok 662 } 663 664 // DeleteBridgeInfo deletes the bridge info of the specified address. 665 func (bm *BridgeManager) DeleteBridgeInfo(addr common.Address) error { 666 bm.bridgesMu.Lock() 667 defer bm.bridgesMu.Unlock() 668 669 bi := bm.bridges[addr] 670 if bi == nil { 671 return ErrNoBridgeInfo 672 } 673 674 close(bi.closed) 675 676 delete(bm.bridges, addr) 677 return nil 678 } 679 680 // SetBridgeInfo stores the address and bridge pair with local/remote and subscription status. 681 func (bm *BridgeManager) SetBridgeInfo(addr common.Address, bridge *bridgecontract.Bridge, cpAddr common.Address, cpBridge *bridgecontract.Bridge, account *accountInfo, local bool, subscribed bool) error { 682 bm.bridgesMu.Lock() 683 defer bm.bridgesMu.Unlock() 684 685 if bm.bridges[addr] != nil { 686 return ErrDuplicatedBridgeInfo 687 } 688 689 var counterpartBackend Backend 690 if local { 691 counterpartBackend = bm.subBridge.remoteBackend 692 } else { 693 counterpartBackend = bm.subBridge.localBackend 694 } 695 696 var err error 697 bm.bridges[addr], err = NewBridgeInfo(bm.subBridge, addr, bridge, cpAddr, cpBridge, account, local, subscribed, counterpartBackend) 698 return err 699 } 700 701 // RestoreBridges setups bridge subscription by using the journal cache. 702 func (bm *BridgeManager) RestoreBridges() error { 703 if bm.subBridge.peers.Len() < 1 { 704 logger.Debug("check peer connections to restore bridges") 705 return ErrBridgeRestore 706 } 707 708 counter := 0 709 bm.stopAllRecoveries() 710 711 bm.journal.cacheMu.RLock() 712 defer bm.journal.cacheMu.RUnlock() 713 714 for _, journal := range bm.journal.cache { 715 cBridgeAddr := journal.ChildAddress 716 pBridgeAddr := journal.ParentAddress 717 bacc := bm.subBridge.bridgeAccounts 718 719 // Set bridge info 720 cBridgeInfo, cOk := bm.GetBridgeInfo(cBridgeAddr) 721 pBridgeInfo, pOk := bm.GetBridgeInfo(pBridgeAddr) 722 723 cBridge, err := bridgecontract.NewBridge(cBridgeAddr, bm.subBridge.localBackend) 724 if err != nil { 725 logger.Error("local bridge creation is failed", "err", err, "bridge", cBridge) 726 break 727 } 728 729 pBridge, err := bridgecontract.NewBridge(pBridgeAddr, bm.subBridge.remoteBackend) 730 if err != nil { 731 logger.Error("remote bridge creation is failed", "err", err, "bridge", pBridge) 732 break 733 } 734 735 if !cOk { 736 err = bm.SetBridgeInfo(cBridgeAddr, cBridge, pBridgeAddr, pBridge, bacc.cAccount, true, false) 737 if err != nil { 738 logger.Error("setting local bridge info is failed", "err", err) 739 bm.DeleteBridgeInfo(cBridgeAddr) 740 break 741 } 742 cBridgeInfo, _ = bm.GetBridgeInfo(cBridgeAddr) 743 } 744 745 if !pOk { 746 err = bm.SetBridgeInfo(pBridgeAddr, pBridge, cBridgeAddr, cBridgeInfo.bridge, bacc.pAccount, false, false) 747 if err != nil { 748 logger.Error("setting remote bridge info is failed", "err", err) 749 bm.DeleteBridgeInfo(pBridgeAddr) 750 break 751 } 752 pBridgeInfo, _ = bm.GetBridgeInfo(pBridgeAddr) 753 } 754 755 // Subscribe bridge events 756 if journal.Subscribed { 757 bm.UnsubscribeEvent(cBridgeAddr) 758 bm.UnsubscribeEvent(pBridgeAddr) 759 760 if !cBridgeInfo.subscribed { 761 logger.Info("automatic local bridge subscription", "info", cBridgeInfo, "address", cBridgeInfo.address.String()) 762 if err := bm.subscribeEvent(cBridgeAddr, cBridgeInfo.bridge); err != nil { 763 logger.Error("local bridge subscription is failed", "err", err) 764 break 765 } 766 } 767 if !pBridgeInfo.subscribed { 768 logger.Info("automatic remote bridge subscription", "info", pBridgeInfo, "address", pBridgeInfo.address.String()) 769 if err := bm.subscribeEvent(pBridgeAddr, pBridgeInfo.bridge); err != nil { 770 logger.Error("remote bridge subscription is failed", "err", err) 771 bm.DeleteBridgeInfo(pBridgeAddr) 772 break 773 } 774 } 775 recovery := bm.recoveries[cBridgeAddr] 776 if recovery == nil { 777 bm.AddRecovery(cBridgeAddr, pBridgeAddr) 778 } 779 } 780 781 counter++ 782 } 783 784 if len(bm.journal.cache) == counter { 785 logger.Info("succeeded to restore bridges", "pairs", counter) 786 return nil 787 } 788 return ErrBridgeRestore 789 } 790 791 // SetJournal inserts or updates journal for a given addresses pair. 792 func (bm *BridgeManager) SetJournal(bridgeAlias string, localAddress, remoteAddress common.Address) error { 793 return bm.journal.insert(bridgeAlias, localAddress, remoteAddress) 794 } 795 796 // AddRecovery starts value transfer recovery for a given addresses pair. 797 func (bm *BridgeManager) AddRecovery(localAddress, remoteAddress common.Address) error { 798 if !bm.subBridge.config.VTRecovery { 799 logger.Info("value transfer recovery is disabled") 800 return nil 801 } 802 803 // Check if bridge information is exist. 804 localBridgeInfo, ok := bm.GetBridgeInfo(localAddress) 805 if !ok { 806 return ErrNoBridgeInfo 807 } 808 remoteBridgeInfo, ok := bm.GetBridgeInfo(remoteAddress) 809 if !ok { 810 return ErrNoBridgeInfo 811 } 812 813 // Create and start value transfer recovery. 814 recovery := NewValueTransferRecovery(bm.subBridge.config, localBridgeInfo, remoteBridgeInfo) 815 recovery.Start() 816 bm.recoveries[localAddress] = recovery // suppose local/remote is always a pair. 817 return nil 818 } 819 820 // DeleteRecovery deletes the journal and stop the value transfer recovery for a given address pair. 821 func (bm *BridgeManager) DeleteRecovery(localAddress, remoteAddress common.Address) error { 822 // Stop the recovery. 823 recovery, ok := bm.recoveries[localAddress] 824 if !ok { 825 return ErrNoRecovery 826 } 827 recovery.Stop() 828 delete(bm.recoveries, localAddress) 829 830 return nil 831 } 832 833 // stopAllRecoveries stops the internal value transfer recoveries. 834 func (bm *BridgeManager) stopAllRecoveries() { 835 for _, recovery := range bm.recoveries { 836 recovery.Stop() 837 } 838 bm.recoveries = make(map[common.Address]*valueTransferRecovery) 839 } 840 841 func (bm *BridgeManager) RegisterOperator(bridgeAddr, operatorAddr common.Address) (common.Hash, error) { 842 bi, exist := bm.GetBridgeInfo(bridgeAddr) 843 844 if !exist { 845 return common.Hash{}, ErrNoBridgeInfo 846 } 847 848 bi.account.Lock() 849 defer bi.account.UnLock() 850 tx, err := bi.bridge.RegisterOperator(bi.account.GenerateTransactOpts(), operatorAddr) 851 if err != nil { 852 return common.Hash{}, err 853 } 854 bi.account.IncNonce() 855 856 return tx.Hash(), nil 857 } 858 859 func (bm *BridgeManager) GetOperators(bridgeAddr common.Address) ([]common.Address, error) { 860 bi, exist := bm.GetBridgeInfo(bridgeAddr) 861 862 if !exist { 863 return nil, ErrNoBridgeInfo 864 } 865 866 return bi.bridge.GetOperatorList(nil) 867 } 868 869 func (bm *BridgeManager) SetValueTransferOperatorThreshold(bridgeAddr common.Address, threshold uint8) (common.Hash, error) { 870 bi, exist := bm.GetBridgeInfo(bridgeAddr) 871 872 if !exist { 873 return common.Hash{}, ErrNoBridgeInfo 874 } 875 876 bi.account.Lock() 877 defer bi.account.UnLock() 878 tx, err := bi.bridge.SetOperatorThreshold(bi.account.GenerateTransactOpts(), voteTypeValueTransfer, threshold) 879 if err != nil { 880 return common.Hash{}, err 881 } 882 bi.account.IncNonce() 883 884 return tx.Hash(), nil 885 } 886 887 func (bm *BridgeManager) GetValueTransferOperatorThreshold(bridgeAddr common.Address) (uint8, error) { 888 bi, exist := bm.GetBridgeInfo(bridgeAddr) 889 890 if !exist { 891 return 0, ErrNoBridgeInfo 892 } 893 894 threshold, err := bi.bridge.OperatorThresholds(nil, voteTypeValueTransfer) 895 if err != nil { 896 return 0, err 897 } 898 899 return threshold, nil 900 } 901 902 // Deploy Bridge SmartContract on same node or remote node 903 func (bm *BridgeManager) DeployBridge(auth *bind.TransactOpts, backend bind.ContractBackend, local bool) (*bridgecontract.Bridge, common.Address, error) { 904 var acc *accountInfo 905 var modeMintBurn bool 906 907 if local { 908 acc = bm.subBridge.bridgeAccounts.cAccount 909 modeMintBurn = true 910 } else { 911 acc = bm.subBridge.bridgeAccounts.pAccount 912 modeMintBurn = false 913 } 914 915 addr, bridge, err := bm.deployBridge(acc, auth, backend, modeMintBurn) 916 if err != nil { 917 return nil, common.Address{}, err 918 } 919 920 return bridge, addr, err 921 } 922 923 // DeployBridge handles actual smart contract deployment. 924 // To create contract, the chain ID, nonce, account key, private key, contract binding and gas price are used. 925 // The deployed contract address, transaction are returned. An error is also returned if any. 926 func (bm *BridgeManager) deployBridge(acc *accountInfo, auth *bind.TransactOpts, backend bind.ContractBackend, modeMintBurn bool) (common.Address, *bridgecontract.Bridge, error) { 927 acc.Lock() 928 addr, tx, contract, err := bridgecontract.DeployBridge(auth, backend, modeMintBurn) 929 if err != nil { 930 logger.Error("Failed to deploy contract.", "err", err) 931 acc.UnLock() 932 return common.Address{}, nil, err 933 } 934 acc.IncNonce() 935 acc.UnLock() 936 937 logger.Info("Bridge is deploying...", "addr", addr, "txHash", tx.Hash().String()) 938 939 back, ok := backend.(bind.DeployBackend) 940 if !ok { 941 logger.Warn("DeployBacked type assertion is failed. Skip WaitDeployed.") 942 return addr, contract, nil 943 } 944 945 timeoutContext, cancelTimeout := context.WithTimeout(context.Background(), 60*time.Second) 946 defer cancelTimeout() 947 948 addr, err = bind.WaitDeployed(timeoutContext, back, tx) 949 if err != nil { 950 logger.Error("Failed to WaitDeployed.", "err", err, "txHash", tx.Hash().String()) 951 return common.Address{}, nil, err 952 } 953 logger.Info("Bridge is deployed.", "addr", addr, "txHash", tx.Hash().String()) 954 return addr, contract, nil 955 } 956 957 // SubscribeEvent registers a subscription of BridgeERC20Received and BridgeTokenWithdrawn 958 func (bm *BridgeManager) SubscribeEvent(addr common.Address) error { 959 bridgeInfo, ok := bm.GetBridgeInfo(addr) 960 if !ok { 961 return ErrNoBridgeInfo 962 } 963 if bridgeInfo.subscribed { 964 return ErrAlreadySubscribed 965 } 966 err := bm.subscribeEvent(addr, bridgeInfo.bridge) 967 if err != nil { 968 return err 969 } 970 971 return nil 972 } 973 974 // resetAllSubscribedEvents resets watch logs and recreates a goroutine loop to handle event messages. 975 func (bm *BridgeManager) ResetAllSubscribedEvents() error { 976 logger.Info("ResetAllSubscribedEvents is called.") 977 978 bm.journal.cacheMu.RLock() 979 defer bm.journal.cacheMu.RUnlock() 980 for _, journal := range bm.journal.cache { 981 if journal.Subscribed { 982 bm.UnsubscribeEvent(journal.ChildAddress) 983 bm.UnsubscribeEvent(journal.ParentAddress) 984 985 bridgeInfo, ok := bm.GetBridgeInfo(journal.ChildAddress) 986 if !ok { 987 logger.Error("ResetAllSubscribedEvents failed to GetBridgeInfo", "localBridge", journal.ChildAddress.String()) 988 return ErrNoBridgeInfo 989 } 990 err := bm.subscribeEvent(journal.ChildAddress, bridgeInfo.bridge) 991 if err != nil { 992 return err 993 } 994 995 bridgeInfo, ok = bm.GetBridgeInfo(journal.ParentAddress) 996 if !ok { 997 logger.Error("ResetAllSubscribedEvents failed to GetBridgeInfo", "remoteBridge", journal.ParentAddress.String()) 998 bm.UnsubscribeEvent(journal.ChildAddress) 999 return ErrNoBridgeInfo 1000 } 1001 err = bm.subscribeEvent(journal.ParentAddress, bridgeInfo.bridge) 1002 if err != nil { 1003 return err 1004 } 1005 } 1006 } 1007 return nil 1008 } 1009 1010 // SubscribeEvent sets watch logs and creates a goroutine loop to handle event messages. 1011 func (bm *BridgeManager) subscribeEvent(addr common.Address, bridge *bridgecontract.Bridge) error { 1012 bm.tokenEventMu.Lock() 1013 defer bm.tokenEventMu.Unlock() 1014 1015 chanReqVT := make(chan *bridgecontract.BridgeRequestValueTransfer, TokenEventChanSize) 1016 chanReqVTencoded := make(chan *bridgecontract.BridgeRequestValueTransferEncoded, TokenEventChanSize) 1017 chanHandleVT := make(chan *bridgecontract.BridgeHandleValueTransfer, TokenEventChanSize) 1018 1019 vtEv, err := bridge.WatchRequestValueTransfer(nil, chanReqVT, nil, nil, nil) 1020 if err != nil { 1021 logger.Error("Failed to watch RequestValueTransfer event", "err", err) 1022 return err 1023 } 1024 bm.receivedEvents[addr] = append(bm.receivedEvents[addr], vtEv) 1025 1026 vtEncodedev, err := bridge.WatchRequestValueTransferEncoded(nil, chanReqVTencoded, nil, nil, nil) 1027 if err != nil { 1028 logger.Error("Failed to watch RequestValueTransferEncoded event", "err", err) 1029 return err 1030 } 1031 bm.receivedEvents[addr] = append(bm.receivedEvents[addr], vtEncodedev) 1032 1033 withdrawnSub, err := bridge.WatchHandleValueTransfer(nil, chanHandleVT, nil, nil, nil) 1034 if err != nil { 1035 logger.Error("Failed to watch HandleValueTransfer event", "err", err) 1036 vtEv.Unsubscribe() 1037 vtEncodedev.Unsubscribe() 1038 delete(bm.receivedEvents, addr) 1039 return err 1040 } 1041 bm.withdrawEvents[addr] = withdrawnSub 1042 1043 bridgeInfo, ok := bm.GetBridgeInfo(addr) 1044 if !ok { 1045 vtEv.Unsubscribe() 1046 vtEncodedev.Unsubscribe() 1047 withdrawnSub.Unsubscribe() 1048 delete(bm.receivedEvents, addr) 1049 delete(bm.withdrawEvents, addr) 1050 return ErrNoBridgeInfo 1051 } 1052 bridgeInfo.subscribed = true 1053 1054 go bm.loop(addr, chanReqVT, chanReqVTencoded, chanHandleVT, vtEv, vtEncodedev, withdrawnSub) 1055 1056 return nil 1057 } 1058 1059 // UnsubscribeEvent cancels the contract's watch logs and initializes the status. 1060 func (bm *BridgeManager) UnsubscribeEvent(addr common.Address) { 1061 bm.tokenEventMu.Lock() 1062 defer bm.tokenEventMu.Unlock() 1063 1064 receivedSub := bm.receivedEvents[addr] 1065 for _, sub := range receivedSub { 1066 sub.Unsubscribe() 1067 } 1068 delete(bm.receivedEvents, addr) 1069 1070 withdrawSub := bm.withdrawEvents[addr] 1071 if withdrawSub != nil { 1072 withdrawSub.Unsubscribe() 1073 delete(bm.withdrawEvents, addr) 1074 } 1075 1076 bridgeInfo, ok := bm.GetBridgeInfo(addr) 1077 if ok { 1078 bridgeInfo.subscribed = false 1079 } 1080 } 1081 1082 // Loop handles subscribed event messages. 1083 func (bm *BridgeManager) loop( 1084 addr common.Address, 1085 chanReqVT <-chan *bridgecontract.BridgeRequestValueTransfer, 1086 chanReqVTencoded <-chan *bridgecontract.BridgeRequestValueTransferEncoded, 1087 chanHandleVT <-chan *bridgecontract.BridgeHandleValueTransfer, 1088 reqVTevSub, reqVTencodedEvSub event.Subscription, 1089 handleEventSub event.Subscription, 1090 ) { 1091 defer reqVTevSub.Unsubscribe() 1092 defer reqVTencodedEvSub.Unsubscribe() 1093 defer handleEventSub.Unsubscribe() 1094 1095 bi, ok := bm.GetBridgeInfo(addr) 1096 if !ok { 1097 logger.Error("bridge information is missing") 1098 return 1099 } 1100 1101 // TODO-Klaytn change goroutine logic for performance 1102 for { 1103 select { 1104 case <-bi.closed: 1105 return 1106 case ev := <-chanReqVT: 1107 bm.reqVTevFeeder.Send(RequestValueTransferEvent{ev}) 1108 case ev := <-chanReqVTencoded: 1109 bm.reqVTevEncodedFeeder.Send(RequestValueTransferEncodedEvent{ev}) 1110 case ev := <-chanHandleVT: 1111 bm.handleEventFeeder.Send(&HandleValueTransferEvent{ev}) 1112 case err := <-reqVTevSub.Err(): 1113 logger.Info("Contract Event Loop Running Stop by receivedSub.Err()", "err", err) 1114 return 1115 case err := <-reqVTencodedEvSub.Err(): 1116 logger.Info("Contract Event Loop Running Stop by receivedSub.Err()", "err", err) 1117 return 1118 case err := <-handleEventSub.Err(): 1119 logger.Info("Contract Event Loop Running Stop by withdrawSub.Err()", "err", err) 1120 return 1121 } 1122 } 1123 } 1124 1125 // Stop closes a subscribed event scope of the bridge manager. 1126 func (bm *BridgeManager) Stop() { 1127 bm.bridgesMu.Lock() 1128 defer bm.bridgesMu.Unlock() 1129 1130 for addr, bi := range bm.bridges { 1131 close(bi.closed) 1132 delete(bm.bridges, addr) 1133 } 1134 1135 bm.scope.Close() 1136 } 1137 1138 // SetERC20Fee set the ERC20 transfer fee on the bridge contract. 1139 func (bm *BridgeManager) SetERC20Fee(bridgeAddr, tokenAddr common.Address, fee *big.Int) (common.Hash, error) { 1140 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1141 if !ok { 1142 return common.Hash{}, ErrNoBridgeInfo 1143 } 1144 1145 auth := bi.account 1146 auth.Lock() 1147 defer auth.UnLock() 1148 1149 rn, err := bi.bridge.ConfigurationNonce(nil) 1150 if err != nil { 1151 return common.Hash{}, err 1152 } 1153 1154 tx, err := bi.bridge.SetERC20Fee(auth.GenerateTransactOpts(), tokenAddr, fee, rn) 1155 if err != nil { 1156 return common.Hash{}, err 1157 } 1158 1159 auth.IncNonce() 1160 1161 return tx.Hash(), nil 1162 } 1163 1164 // SetKLAYFee set the KLAY transfer fee on the bridge contract. 1165 func (bm *BridgeManager) SetKLAYFee(bridgeAddr common.Address, fee *big.Int) (common.Hash, error) { 1166 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1167 if !ok { 1168 return common.Hash{}, ErrNoBridgeInfo 1169 } 1170 1171 auth := bi.account 1172 auth.Lock() 1173 defer auth.UnLock() 1174 1175 rn, err := bi.bridge.ConfigurationNonce(nil) 1176 if err != nil { 1177 return common.Hash{}, err 1178 } 1179 1180 tx, err := bi.bridge.SetKLAYFee(auth.GenerateTransactOpts(), fee, rn) 1181 if err != nil { 1182 return common.Hash{}, err 1183 } 1184 1185 auth.IncNonce() 1186 1187 return tx.Hash(), nil 1188 } 1189 1190 // SetFeeReceiver set the fee receiver which can get the fee of value transfer request. 1191 func (bm *BridgeManager) SetFeeReceiver(bridgeAddr, receiver common.Address) (common.Hash, error) { 1192 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1193 if !ok { 1194 return common.Hash{}, ErrNoBridgeInfo 1195 } 1196 1197 auth := bi.account 1198 auth.Lock() 1199 defer auth.UnLock() 1200 1201 tx, err := bi.bridge.SetFeeReceiver(auth.GenerateTransactOpts(), receiver) 1202 if err != nil { 1203 return common.Hash{}, err 1204 } 1205 1206 auth.IncNonce() 1207 1208 return tx.Hash(), nil 1209 } 1210 1211 // GetERC20Fee returns the ERC20 transfer fee on the bridge contract. 1212 func (bm *BridgeManager) GetERC20Fee(bridgeAddr, tokenAddr common.Address) (*big.Int, error) { 1213 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1214 if !ok { 1215 return nil, ErrNoBridgeInfo 1216 } 1217 1218 return bi.bridge.FeeOfERC20(nil, tokenAddr) 1219 } 1220 1221 // GetKLAYFee returns the KLAY transfer fee on the bridge contract. 1222 func (bm *BridgeManager) GetKLAYFee(bridgeAddr common.Address) (*big.Int, error) { 1223 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1224 if !ok { 1225 return nil, ErrNoBridgeInfo 1226 } 1227 1228 return bi.bridge.FeeOfKLAY(nil) 1229 } 1230 1231 // GetFeeReceiver returns the receiver which can get fee of value transfer request. 1232 func (bm *BridgeManager) GetFeeReceiver(bridgeAddr common.Address) (common.Address, error) { 1233 bi, ok := bm.GetBridgeInfo(bridgeAddr) 1234 if !ok { 1235 return common.Address{}, ErrNoBridgeInfo 1236 } 1237 1238 return bi.bridge.FeeReceiver(nil) 1239 } 1240 1241 // IsInParentAddrs returns true if the bridgeAddr is in the list of parent bridge addresses and returns false if not. 1242 func (bm *BridgeManager) IsInParentAddrs(bridgeAddr common.Address) bool { 1243 bm.journal.cacheMu.RLock() 1244 defer bm.journal.cacheMu.RUnlock() 1245 1246 for _, journal := range bm.journal.cache { 1247 if journal.ParentAddress == bridgeAddr { 1248 return true 1249 } 1250 } 1251 return false 1252 } 1253 1254 // IsInChildAddrs returns true if the bridgeAddr is in the list of child bridge addresses and returns false if not. 1255 func (bm *BridgeManager) IsInChildAddrs(bridgeAddr common.Address) bool { 1256 bm.journal.cacheMu.RLock() 1257 defer bm.journal.cacheMu.RUnlock() 1258 1259 for _, journal := range bm.journal.cache { 1260 if journal.ChildAddress == bridgeAddr { 1261 return true 1262 } 1263 } 1264 return false 1265 }