github.com/bcskill/bcschain/v3@v3.4.9-beta2/core/events.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "fmt" 21 "reflect" 22 "sync" 23 "time" 24 25 "github.com/bcskill/bcschain/v3/common" 26 "github.com/bcskill/bcschain/v3/core/types" 27 "github.com/bcskill/bcschain/v3/log" 28 ) 29 30 const timeout = 500 * time.Millisecond 31 32 // NewTxsEvent is posted when a batch of transactions enter the transaction pool. 33 type NewTxsEvent struct{ Txs []*types.Transaction } 34 35 // PendingLogsEvent is posted pre mining and notifies of pending logs. 36 type PendingLogsEvent struct { 37 Logs []*types.Log 38 } 39 40 // PendingStateEvent is posted pre mining and notifies of pending state changes. 41 type PendingStateEvent struct{} 42 43 // NewMinedBlockEvent is posted when a block has been imported. 44 type NewMinedBlockEvent struct{ Block *types.Block } 45 46 // RemovedLogsEvent is posted when a reorg happens 47 type RemovedLogsEvent struct{ Logs []*types.Log } 48 49 type ChainEvent struct { 50 Block *types.Block 51 Hash common.Hash 52 Logs []*types.Log 53 } 54 55 type ChainSideEvent struct { 56 Block *types.Block 57 } 58 59 type ChainHeadEvent struct{ Block *types.Block } 60 61 type NewTxsFeed struct { 62 mu sync.RWMutex 63 subs map[chan<- NewTxsEvent]string 64 } 65 66 func (f *NewTxsFeed) Close() { 67 f.mu.Lock() 68 defer f.mu.Unlock() 69 for sub := range f.subs { 70 close(sub) 71 } 72 f.subs = nil 73 } 74 75 func (f *NewTxsFeed) Subscribe(ch chan<- NewTxsEvent, name string) { 76 f.mu.Lock() 77 defer f.mu.Unlock() 78 if f.subs == nil { 79 f.subs = make(map[chan<- NewTxsEvent]string) 80 } 81 f.subs[ch] = name 82 } 83 84 func (f *NewTxsFeed) Unsubscribe(ch chan<- NewTxsEvent) { 85 f.mu.Lock() 86 defer f.mu.Unlock() 87 if _, ok := f.subs[ch]; ok { 88 delete(f.subs, ch) 89 close(ch) 90 } 91 } 92 93 func (f *NewTxsFeed) Send(ev NewTxsEvent) { 94 f.mu.RLock() 95 defer f.mu.RUnlock() 96 for sub, name := range f.subs { 97 select { 98 case sub <- ev: 99 default: 100 start := time.Now() 101 var action string 102 select { 103 case sub <- ev: 104 action = "delayed" 105 case <-time.After(timeout): 106 action = "dropped" 107 } 108 dur := time.Since(start) 109 log.Warn(fmt.Sprintf("NewTxsFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "txs", len(ev.Txs)) 110 } 111 } 112 } 113 114 type ChainFeed struct { 115 mu sync.RWMutex 116 subs map[chan<- ChainEvent]string 117 } 118 119 func (f *ChainFeed) Close() { 120 f.mu.Lock() 121 defer f.mu.Unlock() 122 for sub := range f.subs { 123 close(sub) 124 } 125 f.subs = nil 126 } 127 128 func (f *ChainFeed) Subscribe(ch chan<- ChainEvent, name string) { 129 f.mu.Lock() 130 defer f.mu.Unlock() 131 if f.subs == nil { 132 f.subs = make(map[chan<- ChainEvent]string) 133 } 134 f.subs[ch] = name 135 } 136 137 func (f *ChainFeed) Unsubscribe(ch chan<- ChainEvent) { 138 f.mu.Lock() 139 defer f.mu.Unlock() 140 if _, ok := f.subs[ch]; ok { 141 delete(f.subs, ch) 142 close(ch) 143 } 144 } 145 146 func (f *ChainFeed) Send(ev ChainEvent) { 147 f.mu.RLock() 148 defer f.mu.RUnlock() 149 for sub, name := range f.subs { 150 select { 151 case sub <- ev: 152 default: 153 start := time.Now() 154 var action string 155 select { 156 case sub <- ev: 157 action = "delayed" 158 case <-time.After(timeout): 159 action = "dropped" 160 } 161 dur := time.Since(start) 162 log.Warn(fmt.Sprintf("ChainFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "block", ev.Block.NumberU64(), "hash", ev.Hash) 163 } 164 } 165 } 166 167 type ChainHeadFeed struct { 168 mu sync.RWMutex 169 subs map[chan<- ChainHeadEvent]string 170 } 171 172 func (f *ChainHeadFeed) Close() { 173 f.mu.Lock() 174 defer f.mu.Unlock() 175 for sub := range f.subs { 176 close(sub) 177 } 178 f.subs = nil 179 } 180 181 func (f *ChainHeadFeed) Subscribe(ch chan<- ChainHeadEvent, name string) { 182 f.mu.Lock() 183 defer f.mu.Unlock() 184 if f.subs == nil { 185 f.subs = make(map[chan<- ChainHeadEvent]string) 186 } 187 f.subs[ch] = name 188 } 189 190 func (f *ChainHeadFeed) Unsubscribe(ch chan<- ChainHeadEvent) { 191 f.mu.Lock() 192 defer f.mu.Unlock() 193 if _, ok := f.subs[ch]; ok { 194 delete(f.subs, ch) 195 close(ch) 196 } 197 } 198 199 func (f *ChainHeadFeed) Send(ev ChainHeadEvent) { 200 f.mu.RLock() 201 defer f.mu.RUnlock() 202 for sub, name := range f.subs { 203 select { 204 case sub <- ev: 205 default: 206 start := time.Now() 207 var action string 208 select { 209 case sub <- ev: 210 action = "delayed" 211 case <-time.After(timeout): 212 action = "dropped" 213 } 214 dur := time.Since(start) 215 log.Warn(fmt.Sprintf("ChainHeadFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "block", ev.Block.NumberU64(), "hash", ev.Block.Hash()) 216 } 217 } 218 } 219 220 type ChainSideFeed struct { 221 mu sync.RWMutex 222 subs map[chan<- ChainSideEvent]string 223 } 224 225 func (f *ChainSideFeed) Close() { 226 f.mu.Lock() 227 defer f.mu.Unlock() 228 for sub := range f.subs { 229 close(sub) 230 } 231 f.subs = nil 232 } 233 234 func (f *ChainSideFeed) Subscribe(ch chan<- ChainSideEvent, name string) { 235 f.mu.Lock() 236 defer f.mu.Unlock() 237 if f.subs == nil { 238 f.subs = make(map[chan<- ChainSideEvent]string) 239 } 240 f.subs[ch] = name 241 } 242 243 func (f *ChainSideFeed) Unsubscribe(ch chan<- ChainSideEvent) { 244 f.mu.Lock() 245 defer f.mu.Unlock() 246 if _, ok := f.subs[ch]; ok { 247 delete(f.subs, ch) 248 close(ch) 249 } 250 } 251 252 func (f *ChainSideFeed) Send(ev ChainSideEvent) { 253 f.mu.RLock() 254 defer f.mu.RUnlock() 255 for sub, name := range f.subs { 256 select { 257 case sub <- ev: 258 default: 259 start := time.Now() 260 var action string 261 select { 262 case sub <- ev: 263 action = "delayed" 264 case <-time.After(timeout): 265 action = "dropped" 266 } 267 dur := time.Since(start) 268 log.Warn(fmt.Sprintf("ChainSideFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "block", ev.Block.NumberU64(), "hash", ev.Block.Hash()) 269 } 270 } 271 } 272 273 type PendingLogsFeed struct { 274 mu sync.RWMutex 275 subs map[chan<- PendingLogsEvent]string 276 } 277 278 func (f *PendingLogsFeed) Close() { 279 f.mu.Lock() 280 defer f.mu.Unlock() 281 for sub := range f.subs { 282 close(sub) 283 } 284 f.subs = nil 285 } 286 287 func (f *PendingLogsFeed) Subscribe(ch chan<- PendingLogsEvent, name string) { 288 f.mu.Lock() 289 defer f.mu.Unlock() 290 if f.subs == nil { 291 f.subs = make(map[chan<- PendingLogsEvent]string) 292 } 293 f.subs[ch] = name 294 } 295 296 func (f *PendingLogsFeed) Unsubscribe(ch chan<- PendingLogsEvent) { 297 f.mu.Lock() 298 defer f.mu.Unlock() 299 if _, ok := f.subs[ch]; ok { 300 delete(f.subs, ch) 301 close(ch) 302 } 303 } 304 305 func (f *PendingLogsFeed) Send(ev PendingLogsEvent) { 306 f.mu.RLock() 307 defer f.mu.RUnlock() 308 for sub, name := range f.subs { 309 select { 310 case sub <- ev: 311 default: 312 start := time.Now() 313 var action string 314 select { 315 case sub <- ev: 316 action = "delayed" 317 case <-time.After(timeout): 318 action = "dropped" 319 } 320 dur := time.Since(start) 321 log.Warn(fmt.Sprintf("PendingLogsFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "len", len(ev.Logs)) 322 } 323 } 324 } 325 326 type RemovedLogsFeed struct { 327 mu sync.RWMutex 328 subs map[chan<- RemovedLogsEvent]string 329 } 330 331 func (f *RemovedLogsFeed) Close() { 332 f.mu.Lock() 333 defer f.mu.Unlock() 334 for sub := range f.subs { 335 close(sub) 336 } 337 f.subs = nil 338 } 339 340 func (f *RemovedLogsFeed) Subscribe(ch chan<- RemovedLogsEvent, name string) { 341 f.mu.Lock() 342 defer f.mu.Unlock() 343 if f.subs == nil { 344 f.subs = make(map[chan<- RemovedLogsEvent]string) 345 } 346 f.subs[ch] = name 347 } 348 349 func (f *RemovedLogsFeed) Unsubscribe(ch chan<- RemovedLogsEvent) { 350 f.mu.Lock() 351 defer f.mu.Unlock() 352 if _, ok := f.subs[ch]; ok { 353 delete(f.subs, ch) 354 close(ch) 355 } 356 } 357 358 func (f *RemovedLogsFeed) Send(ev RemovedLogsEvent) { 359 f.mu.RLock() 360 defer f.mu.RUnlock() 361 for sub, name := range f.subs { 362 select { 363 case sub <- ev: 364 default: 365 start := time.Now() 366 var action string 367 select { 368 case sub <- ev: 369 action = "delayed" 370 case <-time.After(timeout): 371 action = "dropped" 372 } 373 dur := time.Since(start) 374 log.Warn(fmt.Sprintf("RemovedLogsFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "len", len(ev.Logs)) 375 } 376 } 377 } 378 379 type LogsFeed struct { 380 mu sync.RWMutex 381 subs map[chan<- []*types.Log]string 382 } 383 384 func (f *LogsFeed) Close() { 385 f.mu.Lock() 386 defer f.mu.Unlock() 387 for sub := range f.subs { 388 close(sub) 389 } 390 f.subs = nil 391 } 392 393 func (f *LogsFeed) Len() int { 394 f.mu.RLock() 395 defer f.mu.RUnlock() 396 return len(f.subs) 397 } 398 399 func (f *LogsFeed) Subscribe(ch chan<- []*types.Log, name string) { 400 f.mu.Lock() 401 defer f.mu.Unlock() 402 if f.subs == nil { 403 f.subs = make(map[chan<- []*types.Log]string) 404 } 405 f.subs[ch] = name 406 } 407 408 func (f *LogsFeed) Unsubscribe(ch chan<- []*types.Log) { 409 f.mu.Lock() 410 defer f.mu.Unlock() 411 if _, ok := f.subs[ch]; ok { 412 delete(f.subs, ch) 413 close(ch) 414 } 415 } 416 417 func (f *LogsFeed) Send(logs []*types.Log) { 418 f.mu.RLock() 419 defer f.mu.RUnlock() 420 for sub, name := range f.subs { 421 select { 422 case sub <- logs: 423 default: 424 start := time.Now() 425 var action string 426 select { 427 case sub <- logs: 428 action = "delayed" 429 case <-time.After(timeout): 430 action = "dropped" 431 } 432 dur := time.Since(start) 433 log.Warn(fmt.Sprintf("LogsFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "len", len(logs)) 434 } 435 } 436 } 437 438 type BlockProcFeed struct { 439 mu sync.RWMutex 440 subs map[chan<- bool]string 441 } 442 443 func (f *BlockProcFeed) Close() { 444 f.mu.Lock() 445 defer f.mu.Unlock() 446 for sub := range f.subs { 447 close(sub) 448 } 449 f.subs = nil 450 } 451 452 func (f *BlockProcFeed) Subscribe(ch chan<- bool, name string) { 453 f.mu.Lock() 454 defer f.mu.Unlock() 455 if f.subs == nil { 456 f.subs = make(map[chan<- bool]string) 457 } 458 f.subs[ch] = name 459 } 460 461 func (f *BlockProcFeed) Unsubscribe(ch chan<- bool) { 462 f.mu.Lock() 463 defer f.mu.Unlock() 464 if _, ok := f.subs[ch]; ok { 465 delete(f.subs, ch) 466 close(ch) 467 } 468 } 469 470 func (f *BlockProcFeed) Send(b bool) { 471 f.mu.RLock() 472 defer f.mu.RUnlock() 473 for sub, name := range f.subs { 474 select { 475 case sub <- b: 476 default: 477 start := time.Now() 478 var action string 479 select { 480 case sub <- b: 481 action = "delayed" 482 case <-time.After(timeout): 483 action = "dropped" 484 } 485 dur := time.Since(start) 486 log.Warn(fmt.Sprintf("BlockProcFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "val", b) 487 } 488 } 489 } 490 491 type Int64Feed struct { 492 mu sync.RWMutex 493 subs map[chan<- int64]string 494 } 495 496 func (f *Int64Feed) Close() { 497 f.mu.Lock() 498 defer f.mu.Unlock() 499 for sub := range f.subs { 500 close(sub) 501 } 502 f.subs = nil 503 } 504 505 func (f *Int64Feed) Subscribe(ch chan<- int64, name string) { 506 f.mu.Lock() 507 defer f.mu.Unlock() 508 if f.subs == nil { 509 f.subs = make(map[chan<- int64]string) 510 } 511 f.subs[ch] = name 512 } 513 514 func (f *Int64Feed) Unsubscribe(ch chan<- int64) { 515 f.mu.Lock() 516 defer f.mu.Unlock() 517 if _, ok := f.subs[ch]; ok { 518 delete(f.subs, ch) 519 close(ch) 520 } 521 } 522 523 func (f *Int64Feed) Send(e int64) { 524 f.mu.RLock() 525 defer f.mu.RUnlock() 526 for sub, name := range f.subs { 527 select { 528 case sub <- e: 529 default: 530 start := time.Now() 531 var action string 532 select { 533 case sub <- e: 534 action = "delayed" 535 case <-time.After(timeout): 536 action = "dropped" 537 } 538 dur := time.Since(start) 539 log.Warn(fmt.Sprintf("Int64Feed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "val", e) 540 } 541 } 542 } 543 544 type IntFeed struct { 545 mu sync.RWMutex 546 subs map[chan<- int]string 547 } 548 549 func (f *IntFeed) Close() { 550 f.mu.Lock() 551 defer f.mu.Unlock() 552 for sub := range f.subs { 553 close(sub) 554 } 555 f.subs = nil 556 } 557 558 func (f *IntFeed) Subscribe(ch chan<- int, name string) { 559 f.mu.Lock() 560 defer f.mu.Unlock() 561 if f.subs == nil { 562 f.subs = make(map[chan<- int]string) 563 } 564 f.subs[ch] = name 565 } 566 567 func (f *IntFeed) Unsubscribe(ch chan<- int) { 568 f.mu.Lock() 569 defer f.mu.Unlock() 570 if _, ok := f.subs[ch]; ok { 571 delete(f.subs, ch) 572 close(ch) 573 } 574 } 575 576 func (f *IntFeed) Send(e int) { 577 f.mu.RLock() 578 defer f.mu.RUnlock() 579 for sub, name := range f.subs { 580 select { 581 case sub <- e: 582 default: 583 start := time.Now() 584 var action string 585 select { 586 case sub <- e: 587 action = "delayed" 588 case <-time.After(timeout): 589 action = "dropped" 590 } 591 dur := time.Since(start) 592 log.Warn(fmt.Sprintf("IntFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "val", e) 593 } 594 } 595 } 596 597 type InterfaceFeed struct { 598 mu sync.RWMutex 599 subs map[chan<- interface{}]string 600 } 601 602 func (f *InterfaceFeed) Close() { 603 f.mu.Lock() 604 defer f.mu.Unlock() 605 for sub := range f.subs { 606 close(sub) 607 } 608 f.subs = nil 609 } 610 611 func (f *InterfaceFeed) Subscribe(ch chan<- interface{}, name string) { 612 f.mu.Lock() 613 defer f.mu.Unlock() 614 if f.subs == nil { 615 f.subs = make(map[chan<- interface{}]string) 616 } 617 f.subs[ch] = name 618 } 619 620 func (f *InterfaceFeed) Unsubscribe(ch chan<- interface{}) { 621 f.mu.Lock() 622 defer f.mu.Unlock() 623 if _, ok := f.subs[ch]; ok { 624 delete(f.subs, ch) 625 close(ch) 626 } 627 } 628 629 func (f *InterfaceFeed) Send(e interface{}) { 630 f.mu.RLock() 631 defer f.mu.RUnlock() 632 for sub, name := range f.subs { 633 select { 634 case sub <- e: 635 default: 636 start := time.Now() 637 var action string 638 select { 639 case sub <- e: 640 action = "delayed" 641 case <-time.After(timeout): 642 action = "dropped" 643 } 644 dur := time.Since(start) 645 log.Warn(fmt.Sprintf("InterfaceFeed send %s: channel full", action), "name", name, "cap", cap(sub), "time", dur, "type", reflect.TypeOf(e)) 646 } 647 } 648 }