                      block-event-handlers
                      tx-id->chan-fn-map
                      chaincode-id->chan-fn-map
-                     observer
                      event-go-loop
-
+                     start-time
+                     end-time
+                     managed-channel
                      ;; connected
                      ;; mtx
                      ;; grpc-client

  [event-hub]
  (letfn [(%get-all-chans [k]
            (map :ch (vals (deref (k event-hub)))))]
    `[(:command-ch ~event-hub)
      (:block-event-chan ~event-hub)
      ~@(%get-all-chans :tx-id->chan-fn-map)
      ~@(%get-all-chans :chaincode-id->chan-fn-map)]))



(defn add-event-go-loop!
  [event-hub]
  (swap! (:command-ch event-hub) (async/chan))
  (swap! (:block-event-chan event-hub) (async/chan (async/sliding-buffer default-sliding-buffer-size)))
  (swap! (:start-time event-hub) (System/currentTimeMillis))
  (swap! (:event-go-loop event-hub)
         (let [command-ch (:command-ch event-hub)]
           (async/go-loop []
             (let [[v ch] (async/alts! (get-all-event-chans event-hub))]
               (cond (and (= command-ch ch) (= v :refresh))
                     :renew-get-all-event-chans

                     (instance? Block v)
                     (doseq [[_ f] @(:block-event-handlers event-hub)]
                       (utils/ignore-errors
                        (f v)))

                     (instance? TxEvent v)
                     (utils/ignore-errors
                      ((:fn (get @(:tx-id->chan-fn-map event-hub) (:tx-id v))) v))

                     (instance? ChaincodeEvent v)
                     (utils/ignore-errors
                      ((:fn (get @(:chaincode-id->chan-fn-map event-hub) (:chaincode-id v))) v)))
               (when-not (and (= command-ch ch) (= v :quit))
                 (recur))))
           ;; When out of the loop, clear ch, event-go-loop, etc
           (.shutdownNow ^ManagedChannel (deref (:managed-channel event-hub)))
           (async/close! (deref (:command-ch event-hub)))
           (async/close! (deref (:block-event-chan event-hub)))
           (swap! (:managed-channel event-hub) nil)
           (swap! (:command-ch event-hub) nil)
           (swap! (:block-event-chan event-hub) nil)
           (swap! (:event-go-loop event-hub) nil)
           (swap! (:end-time event-hub) (System/currentTimeMillis)))))

(defn- %id->ch
  [event-hub id k]
