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  */