github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/consensus/debug.go (about) 1 package consensus 2 3 /* 4 5 Something like this could be useful, but currently our state machine doesn't 6 emit all the round step events expected, say to break on PrecommitWait (no 7 EventNewRoundStep is emitted). So far it's been fine to just subscribe/ensure 8 as the tests already do, so this abstraction maybe isn't useful. 9 10 type debugger struct { 11 rsChan <-chan events.Event // event.NewRoundStep's 12 newBreakChan chan cstypes.HRS // new breaks 13 didBreakChan chan chan<- struct{} // close chan struct{} to resume 14 breakHRS cstypes.HRS 15 } 16 17 func makeDebugger(cs *ConsensusState) *debugger { 18 dbg := &debugger{ 19 rsChan: subscribe(cs.evsw, cstypes.EventNewRoundStep{}), 20 newBreakChan: make(chan cstypes.HRS, 0), 21 didBreakChan: make(chan chan<- struct{}, 0), 22 breakHRS: cstypes.HRS{}, 23 } 24 go dbg.listenRoutine() 25 return dbg 26 } 27 28 func (dbg *debugger) listenRoutine() { 29 for { 30 select { 31 case event, ok := <-dbg.rsChan: 32 if !ok { 33 return // done 34 } 35 if dbg.breakHRS.IsHRSZero() { 36 continue 37 } 38 newStepEvent := event.(cstypes.EventNewRoundStep) 39 if dbg.breakHRS.Compare(newStepEvent.HRS) <= 0 { 40 resumeChan := make(chan struct{}, 0) 41 dbg.didBreakChan <- resumeChan // block once 42 // OnBreak() 43 <-resumeChan // block twice 44 dbg.breakHRS = cstypes.HRS{} // reset 45 } else { 46 // TODO use some log 47 fmt.Printf("[INFO] ignoring event that comes before breakpoint %v\n", event) 48 continue 49 } 50 case breakHRS := <-dbg.newBreakChan: 51 if dbg.breakHRS.IsHRSZero() { 52 dbg.breakHRS = breakHRS 53 } else { 54 panic("debugger breakpoint already set") 55 } 56 } 57 } 58 } 59 60 func (dbg *debugger) SetBreak(hrs cstypes.HRS) { 61 dbg.newBreakChan <- hrs 62 } 63 64 func (dbg *debugger) OnBreak(cb func()) { 65 resumeChan := <-dbg.didBreakChan // block until break 66 cb() // run callback body 67 close(resumeChan) // resume 68 } 69 70 */