@@ -19,6 +19,7 @@ type Engine struct {
1919 blockSizeInBytes int
2020 blockRate time.Duration
2121 blockChan chan * types.Block
22+ signalChan chan * types.Signal
2223 prevBlock * types.Block
2324 finalBlock * types.Block
2425}
@@ -35,6 +36,7 @@ func NewEngine(genesisHash string, genesisHeight uint64, genesisTime time.Time,
3536 blockRate : blockRate ,
3637 blockSizeInBytes : blockSizeInBytes ,
3738 blockChan : make (chan * types.Block ),
39+ signalChan : make (chan * types.Signal ),
3840 }
3941}
4042
@@ -49,7 +51,7 @@ func (e *Engine) Initialize(prevBlock *types.Block, finalBlock *types.Block) err
4951 return nil
5052}
5153
52- func (e * Engine ) StartBlockProduction (ctx context.Context ) {
54+ func (e * Engine ) StartBlockProduction (ctx context.Context , withSignal bool ) {
5355 ticker := time .NewTicker (e .blockRate )
5456
5557 logrus .WithField ("rate" , e .blockRate ).Info ("starting block producer" )
@@ -60,18 +62,47 @@ func (e *Engine) StartBlockProduction(ctx context.Context) {
6062 }
6163 }
6264
65+ var lastBlock * types.Block
66+ var lastSignal * types.Signal
67+
68+ signalTicker := time .NewTicker (e .blockRate )
69+ if withSignal {
70+ <- time .After (e .blockRate / 2 ) // offset by half duration
71+ signalTicker .Reset (e .blockRate )
72+ } else {
73+ signalTicker .Stop ()
74+ }
75+
6376 for {
6477 select {
6578 case <- ticker .C :
6679 for _ , block := range e .createBlocks () {
6780 e .blockChan <- block
81+ lastBlock = block
6882
6983 if e .stopHeight > 0 && block .Header .Height >= e .stopHeight {
7084 logrus .Info ("reached stop height" )
7185 ticker .Stop ()
7286 return
7387 }
7488 }
89+ case <- signalTicker .C :
90+ if ! withSignal {
91+ continue // just ignore if a signal ticker comes in, but it actually should not be called because of the Stop(), unless there is a crazy race condtition
92+ }
93+ if lastBlock != nil {
94+ if lastSignal != nil && lastSignal .BlockID == lastBlock .Header .Hash {
95+ continue // don't send duplicate signal
96+ }
97+ sig := & types.Signal {
98+ BlockID : lastBlock .Header .Hash ,
99+ BlockNumber : lastBlock .Header .Height ,
100+ CommitmentLevel : 10 ,
101+ }
102+ e .signalChan <- sig
103+ lastSignal = sig
104+ }
105+
75106 case <- ctx .Done ():
76107 logrus .Info ("stopping block producer" )
77108 close (e .blockChan )
@@ -80,10 +111,14 @@ func (e *Engine) StartBlockProduction(ctx context.Context) {
80111 }
81112}
82113
83- func (e * Engine ) Subscription () <- chan * types.Block {
114+ func (e * Engine ) SubscribeBlocks () <- chan * types.Block {
84115 return e .blockChan
85116}
86117
118+ func (e * Engine ) SubscribeSignals () <- chan * types.Signal {
119+ return e .signalChan
120+ }
121+
87122func (e * Engine ) createBlocks () (out []* types.Block ) {
88123 if e .prevBlock == nil {
89124 genesisBlock := types .GenesisBlock (e .genesisHash , e .genesisHeight , e .genesisTime )
0 commit comments