diff --git a/command/chain_watch.go b/command/chain_watch.go
new file mode 100644
index 0000000000000000000000000000000000000000..53b76eb86a7d4f35d0caae19986daabda0657e63
--- /dev/null
+++ b/command/chain_watch.go
@@ -0,0 +1,89 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/signal"
+	"syscall"
+
+	"github.com/ethereum/go-ethereum/command/flagset"
+	"github.com/ethereum/go-ethereum/command/server/proto"
+	"github.com/ethereum/go-ethereum/core"
+)
+
+// ChainWatchCommand is the command to group the peers commands
+type ChainWatchCommand struct {
+	*Meta2
+}
+
+// Help implements the cli.Command interface
+func (c *ChainWatchCommand) Help() string {
+	return `Usage: bor chain watch
+
+  This command is used to view the chainHead, reorg and fork events in real-time`
+}
+
+func (c *ChainWatchCommand) Flags() *flagset.Flagset {
+	flags := c.NewFlagSet("chain watch")
+
+	return flags
+}
+
+// Synopsis implements the cli.Command interface
+func (c *ChainWatchCommand) Synopsis() string {
+	return "Watch the chainHead, reorg and fork events in real-time"
+}
+
+// Run implements the cli.Command interface
+func (c *ChainWatchCommand) Run(args []string) int {
+	flags := c.Flags()
+	if err := flags.Parse(args); err != nil {
+		c.UI.Error(err.Error())
+		return 1
+	}
+
+	borClt, err := c.BorConn()
+	if err != nil {
+		c.UI.Error(err.Error())
+		return 1
+	}
+
+	sub, err := borClt.ChainWatch(context.Background(), &proto.ChainWatchRequest{})
+	if err != nil {
+		c.UI.Error(err.Error())
+		return 1
+	}
+
+	signalCh := make(chan os.Signal, 1)
+	signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
+
+	go func() {
+		<-signalCh
+		sub.CloseSend()
+	}()
+
+	for {
+		msg, err := sub.Recv()
+		if err != nil {
+			// if err == EOF if finished on the other side
+			c.UI.Output(err.Error())
+			break
+		}
+		c.UI.Output(formatHeadEvent(msg))
+	}
+
+	return 0
+}
+
+func formatHeadEvent(msg *proto.ChainWatchResponse) string {
+	var out string
+	if msg.Type == core.Chain2HeadCanonicalEvent {
+		out = fmt.Sprintf("Block Added : %v", msg.Newchain)
+	} else if msg.Type == core.Chain2HeadForkEvent {
+		out = fmt.Sprintf("New Fork Block : %v", msg.Newchain)
+	} else if msg.Type == core.Chain2HeadReorgEvent {
+		out = fmt.Sprintf("Reorg Detected \nAdded : %v \nRemoved : %v", msg.Newchain, msg.Oldchain)
+	}
+	return out
+}
diff --git a/command/main.go b/command/main.go
index a2e5a629a7ad93bc3da255b1604ba6c12de6cd09..31b8bf92d7164fb0f8491003e9871d990e9e985f 100644
--- a/command/main.go
+++ b/command/main.go
@@ -69,6 +69,11 @@ func commands() map[string]cli.CommandFactory {
 				UI: ui,
 			}, nil
 		},
+		"chain watch": func() (cli.Command, error) {
+			return &ChainWatchCommand{
+				Meta2: meta2,
+			}, nil
+		},
 		"chain sethead": func() (cli.Command, error) {
 			return &ChainSetHeadCommand{
 				Meta2: meta2,
diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go
index d1a5ed77b2b3b25a947df24c4c7cff9b30a6ba40..a709c538ae9a0062e82aa7098610e5392f999cbf 100644
--- a/command/server/proto/server.pb.go
+++ b/command/server/proto/server.pb.go
@@ -1,16 +1,16 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.25.0
-// 	protoc        v3.12.0
+// 	protoc        v3.17.3
 // source: command/server/proto/server.proto
 
 package proto
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	empty "github.com/golang/protobuf/ptypes/empty"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 	reflect "reflect"
 	sync "sync"
 )
@@ -72,7 +72,163 @@ func (x PprofRequest_Type) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use PprofRequest_Type.Descriptor instead.
 func (PprofRequest_Type) EnumDescriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{13, 0}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{16, 0}
+}
+
+type ChainWatchRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ChainWatchRequest) Reset() {
+	*x = ChainWatchRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_command_server_proto_server_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainWatchRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainWatchRequest) ProtoMessage() {}
+
+func (x *ChainWatchRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_command_server_proto_server_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainWatchRequest.ProtoReflect.Descriptor instead.
+func (*ChainWatchRequest) Descriptor() ([]byte, []int) {
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{0}
+}
+
+type ChainWatchResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Oldchain []*BlockStub `protobuf:"bytes,1,rep,name=oldchain,proto3" json:"oldchain,omitempty"`
+	Newchain []*BlockStub `protobuf:"bytes,2,rep,name=newchain,proto3" json:"newchain,omitempty"`
+	Type     string       `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
+}
+
+func (x *ChainWatchResponse) Reset() {
+	*x = ChainWatchResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_command_server_proto_server_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainWatchResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainWatchResponse) ProtoMessage() {}
+
+func (x *ChainWatchResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_command_server_proto_server_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainWatchResponse.ProtoReflect.Descriptor instead.
+func (*ChainWatchResponse) Descriptor() ([]byte, []int) {
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ChainWatchResponse) GetOldchain() []*BlockStub {
+	if x != nil {
+		return x.Oldchain
+	}
+	return nil
+}
+
+func (x *ChainWatchResponse) GetNewchain() []*BlockStub {
+	if x != nil {
+		return x.Newchain
+	}
+	return nil
+}
+
+func (x *ChainWatchResponse) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+type BlockStub struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Hash   string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
+	Number uint64 `protobuf:"varint,2,opt,name=number,proto3" json:"number,omitempty"`
+}
+
+func (x *BlockStub) Reset() {
+	*x = BlockStub{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_command_server_proto_server_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BlockStub) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BlockStub) ProtoMessage() {}
+
+func (x *BlockStub) ProtoReflect() protoreflect.Message {
+	mi := &file_command_server_proto_server_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BlockStub.ProtoReflect.Descriptor instead.
+func (*BlockStub) Descriptor() ([]byte, []int) {
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *BlockStub) GetHash() string {
+	if x != nil {
+		return x.Hash
+	}
+	return ""
+}
+
+func (x *BlockStub) GetNumber() uint64 {
+	if x != nil {
+		return x.Number
+	}
+	return 0
 }
 
 type PeersAddRequest struct {
@@ -87,7 +243,7 @@ type PeersAddRequest struct {
 func (x *PeersAddRequest) Reset() {
 	*x = PeersAddRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[0]
+		mi := &file_command_server_proto_server_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -100,7 +256,7 @@ func (x *PeersAddRequest) String() string {
 func (*PeersAddRequest) ProtoMessage() {}
 
 func (x *PeersAddRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[0]
+	mi := &file_command_server_proto_server_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -113,7 +269,7 @@ func (x *PeersAddRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersAddRequest.ProtoReflect.Descriptor instead.
 func (*PeersAddRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{0}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *PeersAddRequest) GetEnode() string {
@@ -139,7 +295,7 @@ type PeersAddResponse struct {
 func (x *PeersAddResponse) Reset() {
 	*x = PeersAddResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[1]
+		mi := &file_command_server_proto_server_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -152,7 +308,7 @@ func (x *PeersAddResponse) String() string {
 func (*PeersAddResponse) ProtoMessage() {}
 
 func (x *PeersAddResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[1]
+	mi := &file_command_server_proto_server_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -165,7 +321,7 @@ func (x *PeersAddResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersAddResponse.ProtoReflect.Descriptor instead.
 func (*PeersAddResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{1}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{4}
 }
 
 type PeersRemoveRequest struct {
@@ -180,7 +336,7 @@ type PeersRemoveRequest struct {
 func (x *PeersRemoveRequest) Reset() {
 	*x = PeersRemoveRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[2]
+		mi := &file_command_server_proto_server_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -193,7 +349,7 @@ func (x *PeersRemoveRequest) String() string {
 func (*PeersRemoveRequest) ProtoMessage() {}
 
 func (x *PeersRemoveRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[2]
+	mi := &file_command_server_proto_server_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -206,7 +362,7 @@ func (x *PeersRemoveRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersRemoveRequest.ProtoReflect.Descriptor instead.
 func (*PeersRemoveRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{2}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *PeersRemoveRequest) GetEnode() string {
@@ -232,7 +388,7 @@ type PeersRemoveResponse struct {
 func (x *PeersRemoveResponse) Reset() {
 	*x = PeersRemoveResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[3]
+		mi := &file_command_server_proto_server_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -245,7 +401,7 @@ func (x *PeersRemoveResponse) String() string {
 func (*PeersRemoveResponse) ProtoMessage() {}
 
 func (x *PeersRemoveResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[3]
+	mi := &file_command_server_proto_server_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -258,7 +414,7 @@ func (x *PeersRemoveResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersRemoveResponse.ProtoReflect.Descriptor instead.
 func (*PeersRemoveResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{3}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{6}
 }
 
 type PeersListRequest struct {
@@ -270,7 +426,7 @@ type PeersListRequest struct {
 func (x *PeersListRequest) Reset() {
 	*x = PeersListRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[4]
+		mi := &file_command_server_proto_server_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -283,7 +439,7 @@ func (x *PeersListRequest) String() string {
 func (*PeersListRequest) ProtoMessage() {}
 
 func (x *PeersListRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[4]
+	mi := &file_command_server_proto_server_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -296,7 +452,7 @@ func (x *PeersListRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersListRequest.ProtoReflect.Descriptor instead.
 func (*PeersListRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{4}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{7}
 }
 
 type PeersListResponse struct {
@@ -310,7 +466,7 @@ type PeersListResponse struct {
 func (x *PeersListResponse) Reset() {
 	*x = PeersListResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[5]
+		mi := &file_command_server_proto_server_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -323,7 +479,7 @@ func (x *PeersListResponse) String() string {
 func (*PeersListResponse) ProtoMessage() {}
 
 func (x *PeersListResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[5]
+	mi := &file_command_server_proto_server_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -336,7 +492,7 @@ func (x *PeersListResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersListResponse.ProtoReflect.Descriptor instead.
 func (*PeersListResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{5}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *PeersListResponse) GetPeers() []*Peer {
@@ -357,7 +513,7 @@ type PeersStatusRequest struct {
 func (x *PeersStatusRequest) Reset() {
 	*x = PeersStatusRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[6]
+		mi := &file_command_server_proto_server_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -370,7 +526,7 @@ func (x *PeersStatusRequest) String() string {
 func (*PeersStatusRequest) ProtoMessage() {}
 
 func (x *PeersStatusRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[6]
+	mi := &file_command_server_proto_server_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -383,7 +539,7 @@ func (x *PeersStatusRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersStatusRequest.ProtoReflect.Descriptor instead.
 func (*PeersStatusRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{6}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{9}
 }
 
 func (x *PeersStatusRequest) GetEnode() string {
@@ -404,7 +560,7 @@ type PeersStatusResponse struct {
 func (x *PeersStatusResponse) Reset() {
 	*x = PeersStatusResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[7]
+		mi := &file_command_server_proto_server_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -417,7 +573,7 @@ func (x *PeersStatusResponse) String() string {
 func (*PeersStatusResponse) ProtoMessage() {}
 
 func (x *PeersStatusResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[7]
+	mi := &file_command_server_proto_server_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -430,7 +586,7 @@ func (x *PeersStatusResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeersStatusResponse.ProtoReflect.Descriptor instead.
 func (*PeersStatusResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{7}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *PeersStatusResponse) GetPeer() *Peer {
@@ -457,7 +613,7 @@ type Peer struct {
 func (x *Peer) Reset() {
 	*x = Peer{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[8]
+		mi := &file_command_server_proto_server_proto_msgTypes[11]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -470,7 +626,7 @@ func (x *Peer) String() string {
 func (*Peer) ProtoMessage() {}
 
 func (x *Peer) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[8]
+	mi := &file_command_server_proto_server_proto_msgTypes[11]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -483,7 +639,7 @@ func (x *Peer) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Peer.ProtoReflect.Descriptor instead.
 func (*Peer) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{8}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{11}
 }
 
 func (x *Peer) GetId() string {
@@ -546,7 +702,7 @@ type ChainSetHeadRequest struct {
 func (x *ChainSetHeadRequest) Reset() {
 	*x = ChainSetHeadRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[9]
+		mi := &file_command_server_proto_server_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -559,7 +715,7 @@ func (x *ChainSetHeadRequest) String() string {
 func (*ChainSetHeadRequest) ProtoMessage() {}
 
 func (x *ChainSetHeadRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[9]
+	mi := &file_command_server_proto_server_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -572,7 +728,7 @@ func (x *ChainSetHeadRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ChainSetHeadRequest.ProtoReflect.Descriptor instead.
 func (*ChainSetHeadRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{9}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{12}
 }
 
 func (x *ChainSetHeadRequest) GetNumber() uint64 {
@@ -591,7 +747,7 @@ type ChainSetHeadResponse struct {
 func (x *ChainSetHeadResponse) Reset() {
 	*x = ChainSetHeadResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[10]
+		mi := &file_command_server_proto_server_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -604,7 +760,7 @@ func (x *ChainSetHeadResponse) String() string {
 func (*ChainSetHeadResponse) ProtoMessage() {}
 
 func (x *ChainSetHeadResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[10]
+	mi := &file_command_server_proto_server_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -617,7 +773,7 @@ func (x *ChainSetHeadResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ChainSetHeadResponse.ProtoReflect.Descriptor instead.
 func (*ChainSetHeadResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{10}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{13}
 }
 
 type StatusResponse struct {
@@ -636,7 +792,7 @@ type StatusResponse struct {
 func (x *StatusResponse) Reset() {
 	*x = StatusResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[11]
+		mi := &file_command_server_proto_server_proto_msgTypes[14]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -649,7 +805,7 @@ func (x *StatusResponse) String() string {
 func (*StatusResponse) ProtoMessage() {}
 
 func (x *StatusResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[11]
+	mi := &file_command_server_proto_server_proto_msgTypes[14]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -662,7 +818,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead.
 func (*StatusResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{11}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14}
 }
 
 func (x *StatusResponse) GetCurrentBlock() *Header {
@@ -719,7 +875,7 @@ type Header struct {
 func (x *Header) Reset() {
 	*x = Header{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[12]
+		mi := &file_command_server_proto_server_proto_msgTypes[15]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -732,7 +888,7 @@ func (x *Header) String() string {
 func (*Header) ProtoMessage() {}
 
 func (x *Header) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[12]
+	mi := &file_command_server_proto_server_proto_msgTypes[15]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -745,7 +901,7 @@ func (x *Header) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Header.ProtoReflect.Descriptor instead.
 func (*Header) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{12}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{15}
 }
 
 func (x *Header) GetHash() string {
@@ -775,7 +931,7 @@ type PprofRequest struct {
 func (x *PprofRequest) Reset() {
 	*x = PprofRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[13]
+		mi := &file_command_server_proto_server_proto_msgTypes[16]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -788,7 +944,7 @@ func (x *PprofRequest) String() string {
 func (*PprofRequest) ProtoMessage() {}
 
 func (x *PprofRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[13]
+	mi := &file_command_server_proto_server_proto_msgTypes[16]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -801,7 +957,7 @@ func (x *PprofRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead.
 func (*PprofRequest) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{13}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{16}
 }
 
 func (x *PprofRequest) GetType() PprofRequest_Type {
@@ -840,7 +996,7 @@ type PprofResponse struct {
 func (x *PprofResponse) Reset() {
 	*x = PprofResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[14]
+		mi := &file_command_server_proto_server_proto_msgTypes[17]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -853,7 +1009,7 @@ func (x *PprofResponse) String() string {
 func (*PprofResponse) ProtoMessage() {}
 
 func (x *PprofResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[14]
+	mi := &file_command_server_proto_server_proto_msgTypes[17]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -866,7 +1022,7 @@ func (x *PprofResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead.
 func (*PprofResponse) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{17}
 }
 
 func (m *PprofResponse) GetEvent() isPprofResponse_Event {
@@ -890,7 +1046,7 @@ func (x *PprofResponse) GetInput() *PprofResponse_Input {
 	return nil
 }
 
-func (x *PprofResponse) GetEof() *empty.Empty {
+func (x *PprofResponse) GetEof() *emptypb.Empty {
 	if x, ok := x.GetEvent().(*PprofResponse_Eof); ok {
 		return x.Eof
 	}
@@ -910,7 +1066,7 @@ type PprofResponse_Input_ struct {
 }
 
 type PprofResponse_Eof struct {
-	Eof *empty.Empty `protobuf:"bytes,3,opt,name=eof,proto3,oneof"`
+	Eof *emptypb.Empty `protobuf:"bytes,3,opt,name=eof,proto3,oneof"`
 }
 
 func (*PprofResponse_Open_) isPprofResponse_Event() {}
@@ -932,7 +1088,7 @@ type StatusResponse_Fork struct {
 func (x *StatusResponse_Fork) Reset() {
 	*x = StatusResponse_Fork{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[15]
+		mi := &file_command_server_proto_server_proto_msgTypes[18]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -945,7 +1101,7 @@ func (x *StatusResponse_Fork) String() string {
 func (*StatusResponse_Fork) ProtoMessage() {}
 
 func (x *StatusResponse_Fork) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[15]
+	mi := &file_command_server_proto_server_proto_msgTypes[18]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -958,7 +1114,7 @@ func (x *StatusResponse_Fork) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StatusResponse_Fork.ProtoReflect.Descriptor instead.
 func (*StatusResponse_Fork) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{11, 0}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 0}
 }
 
 func (x *StatusResponse_Fork) GetName() string {
@@ -995,7 +1151,7 @@ type StatusResponse_Syncing struct {
 func (x *StatusResponse_Syncing) Reset() {
 	*x = StatusResponse_Syncing{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[16]
+		mi := &file_command_server_proto_server_proto_msgTypes[19]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1008,7 +1164,7 @@ func (x *StatusResponse_Syncing) String() string {
 func (*StatusResponse_Syncing) ProtoMessage() {}
 
 func (x *StatusResponse_Syncing) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[16]
+	mi := &file_command_server_proto_server_proto_msgTypes[19]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1021,7 +1177,7 @@ func (x *StatusResponse_Syncing) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StatusResponse_Syncing.ProtoReflect.Descriptor instead.
 func (*StatusResponse_Syncing) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{11, 1}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 1}
 }
 
 func (x *StatusResponse_Syncing) GetStartingBlock() int64 {
@@ -1057,7 +1213,7 @@ type PprofResponse_Open struct {
 func (x *PprofResponse_Open) Reset() {
 	*x = PprofResponse_Open{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[17]
+		mi := &file_command_server_proto_server_proto_msgTypes[20]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1070,7 +1226,7 @@ func (x *PprofResponse_Open) String() string {
 func (*PprofResponse_Open) ProtoMessage() {}
 
 func (x *PprofResponse_Open) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[17]
+	mi := &file_command_server_proto_server_proto_msgTypes[20]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1083,7 +1239,7 @@ func (x *PprofResponse_Open) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PprofResponse_Open.ProtoReflect.Descriptor instead.
 func (*PprofResponse_Open) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 0}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{17, 0}
 }
 
 func (x *PprofResponse_Open) GetHeaders() map[string]string {
@@ -1111,7 +1267,7 @@ type PprofResponse_Input struct {
 func (x *PprofResponse_Input) Reset() {
 	*x = PprofResponse_Input{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_command_server_proto_server_proto_msgTypes[18]
+		mi := &file_command_server_proto_server_proto_msgTypes[21]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1124,7 +1280,7 @@ func (x *PprofResponse_Input) String() string {
 func (*PprofResponse_Input) ProtoMessage() {}
 
 func (x *PprofResponse_Input) ProtoReflect() protoreflect.Message {
-	mi := &file_command_server_proto_server_proto_msgTypes[18]
+	mi := &file_command_server_proto_server_proto_msgTypes[21]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1137,7 +1293,7 @@ func (x *PprofResponse_Input) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PprofResponse_Input.ProtoReflect.Descriptor instead.
 func (*PprofResponse_Input) Descriptor() ([]byte, []int) {
-	return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 1}
+	return file_command_server_proto_server_proto_rawDescGZIP(), []int{17, 1}
 }
 
 func (x *PprofResponse_Input) GetData() []byte {
@@ -1154,140 +1310,157 @@ var file_command_server_proto_server_proto_rawDesc = []byte{
 	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
 	0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67,
 	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74,
-	0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x0f, 0x50, 0x65, 0x65, 0x72, 0x73,
-	0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e,
-	0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65,
-	0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x50, 0x65,
-	0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44,
-	0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72,
-	0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75,
-	0x73, 0x74, 0x65, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d,
-	0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x50,
-	0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
-	0x36, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72,
-	0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x73,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a,
-	0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e,
-	0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x70, 0x65,
-	0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x04,
-	0x50, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e,
-	0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x72, 0x12, 0x12, 0x0a, 0x04,
-	0x63, 0x61, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63, 0x61, 0x70, 0x73,
-	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18,
-	0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
-	0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x2d, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53,
-	0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a,
-	0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e,
-	0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65,
-	0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x03,
-	0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x31, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48,
-	0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c,
-	0x6f, 0x63, 0x6b, 0x12, 0x33, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x65,
-	0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65,
-	0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x50,
-	0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x50,
-	0x65, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65,
-	0x12, 0x37, 0x0a, 0x07, 0x73, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67,
-	0x52, 0x07, 0x73, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x66, 0x6f, 0x72,
-	0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e,
-	0x46, 0x6f, 0x72, 0x6b, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73, 0x1a, 0x4c, 0x0a, 0x04, 0x46,
-	0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1a, 0x0a,
-	0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x77, 0x0a, 0x07, 0x53, 0x79, 0x6e,
-	0x63, 0x69, 0x6e, 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67,
-	0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x74, 0x61,
-	0x72, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x69,
-	0x67, 0x68, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
-	0x52, 0x0c, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x22,
-	0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f,
-	0x63, 0x6b, 0x22, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04,
-	0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68,
-	0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
-	0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, 0x70, 0x72,
-	0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, 0x70,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
-	0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70,
-	0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69,
-	0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
-	0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, 0x12,
-	0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43,
-	0x45, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f,
-	0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x48, 0x00,
-	0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70,
-	0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x70, 0x75,
-	0x74, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x2a, 0x0a, 0x03, 0x65, 0x6f,
-	0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48,
-	0x00, 0x52, 0x03, 0x65, 0x6f, 0x66, 0x1a, 0x98, 0x01, 0x0a, 0x04, 0x4f, 0x70, 0x65, 0x6e, 0x12,
-	0x40, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x64,
-	0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
-	0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
-	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
-	0x01, 0x1a, 0x1b, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61,
-	0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x07,
-	0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x32, 0xc6, 0x03, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12,
-	0x34, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64,
-	0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41,
-	0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76,
-	0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52,
-	0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72,
-	0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65,
-	0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72,
-	0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x13, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x84, 0x01, 0x0a,
+	0x12, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c,
+	0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x62, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x63, 0x68, 0x61, 0x69,
+	0x6e, 0x12, 0x2c, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63,
+	0x6b, 0x53, 0x74, 0x75, 0x62, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12,
+	0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
+	0x79, 0x70, 0x65, 0x22, 0x37, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x62,
+	0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x41, 0x0a, 0x0f,
+	0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+	0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22,
+	0x12, 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x44, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f,
+	0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f,
+	0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12,
+	0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x50, 0x65, 0x65,
+	0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x12, 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65,
+	0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12,
 	0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47,
-	0x0a, 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x12, 0x1a,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48,
-	0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72,
-	0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x33,
+	0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72,
+	0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1f, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72,
+	0x22, 0x98, 0x01, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f,
+	0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12,
+	0x10, 0x0a, 0x03, 0x65, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e,
+	0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x61, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52,
+	0x04, 0x63, 0x61, 0x70, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75,
+	0x73, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73,
+	0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x2d, 0x0a, 0x13, 0x43,
+	0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0xe2, 0x03, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
+	0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72,
+	0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x33, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72,
+	0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0d,
+	0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a,
+	0x08, 0x6e, 0x75, 0x6d, 0x50, 0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x08, 0x6e, 0x75, 0x6d, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79, 0x6e,
+	0x63, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x6e,
+	0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x73, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x79,
+	0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x30,
+	0x0a, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73,
+	0x1a, 0x4c, 0x0a, 0x04, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,
+	0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x62, 0x6c, 0x6f,
+	0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x77,
+	0x0a, 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61,
+	0x72, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12,
+	0x22, 0x0a, 0x0c, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x42, 0x6c,
+	0x6f, 0x63, 0x6b, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c,
+	0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65,
+	0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65,
+	0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x98, 0x01,
+	0x0a, 0x0c, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c,
+	0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
+	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
+	0x22, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b,
+	0x55, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a,
+	0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0d, 0x50, 0x70, 0x72,
+	0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6f, 0x70,
+	0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f,
+	0x70, 0x65, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69,
+	0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12,
+	0x2a, 0x0a, 0x03, 0x65, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
+	0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x03, 0x65, 0x6f, 0x66, 0x1a, 0x98, 0x01, 0x0a, 0x04,
+	0x4f, 0x70, 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70,
+	0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e,
+	0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68,
+	0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65,
+	0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
+	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x1b, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64,
+	0x61, 0x74, 0x61, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x32, 0x8b, 0x04, 0x0a,
+	0x03, 0x42, 0x6f, 0x72, 0x12, 0x34, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65,
+	0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50,
+	0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73,
+	0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50,
+	0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52,
+	0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a,
+	0x09, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72,
+	0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a,
+	0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48,
+	0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69,
+	0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74,
+	0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x57, 0x61,
+	0x74, 0x63, 0x68, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69,
+	0x6e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63,
+	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1303,62 +1476,69 @@ func file_command_server_proto_server_proto_rawDescGZIP() []byte {
 }
 
 var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
+var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
 var file_command_server_proto_server_proto_goTypes = []interface{}{
 	(PprofRequest_Type)(0),         // 0: proto.PprofRequest.Type
-	(*PeersAddRequest)(nil),        // 1: proto.PeersAddRequest
-	(*PeersAddResponse)(nil),       // 2: proto.PeersAddResponse
-	(*PeersRemoveRequest)(nil),     // 3: proto.PeersRemoveRequest
-	(*PeersRemoveResponse)(nil),    // 4: proto.PeersRemoveResponse
-	(*PeersListRequest)(nil),       // 5: proto.PeersListRequest
-	(*PeersListResponse)(nil),      // 6: proto.PeersListResponse
-	(*PeersStatusRequest)(nil),     // 7: proto.PeersStatusRequest
-	(*PeersStatusResponse)(nil),    // 8: proto.PeersStatusResponse
-	(*Peer)(nil),                   // 9: proto.Peer
-	(*ChainSetHeadRequest)(nil),    // 10: proto.ChainSetHeadRequest
-	(*ChainSetHeadResponse)(nil),   // 11: proto.ChainSetHeadResponse
-	(*StatusResponse)(nil),         // 12: proto.StatusResponse
-	(*Header)(nil),                 // 13: proto.Header
-	(*PprofRequest)(nil),           // 14: proto.PprofRequest
-	(*PprofResponse)(nil),          // 15: proto.PprofResponse
-	(*StatusResponse_Fork)(nil),    // 16: proto.StatusResponse.Fork
-	(*StatusResponse_Syncing)(nil), // 17: proto.StatusResponse.Syncing
-	(*PprofResponse_Open)(nil),     // 18: proto.PprofResponse.Open
-	(*PprofResponse_Input)(nil),    // 19: proto.PprofResponse.Input
-	nil,                            // 20: proto.PprofResponse.Open.HeadersEntry
-	(*empty.Empty)(nil),            // 21: google.protobuf.Empty
+	(*ChainWatchRequest)(nil),      // 1: proto.ChainWatchRequest
+	(*ChainWatchResponse)(nil),     // 2: proto.ChainWatchResponse
+	(*BlockStub)(nil),              // 3: proto.BlockStub
+	(*PeersAddRequest)(nil),        // 4: proto.PeersAddRequest
+	(*PeersAddResponse)(nil),       // 5: proto.PeersAddResponse
+	(*PeersRemoveRequest)(nil),     // 6: proto.PeersRemoveRequest
+	(*PeersRemoveResponse)(nil),    // 7: proto.PeersRemoveResponse
+	(*PeersListRequest)(nil),       // 8: proto.PeersListRequest
+	(*PeersListResponse)(nil),      // 9: proto.PeersListResponse
+	(*PeersStatusRequest)(nil),     // 10: proto.PeersStatusRequest
+	(*PeersStatusResponse)(nil),    // 11: proto.PeersStatusResponse
+	(*Peer)(nil),                   // 12: proto.Peer
+	(*ChainSetHeadRequest)(nil),    // 13: proto.ChainSetHeadRequest
+	(*ChainSetHeadResponse)(nil),   // 14: proto.ChainSetHeadResponse
+	(*StatusResponse)(nil),         // 15: proto.StatusResponse
+	(*Header)(nil),                 // 16: proto.Header
+	(*PprofRequest)(nil),           // 17: proto.PprofRequest
+	(*PprofResponse)(nil),          // 18: proto.PprofResponse
+	(*StatusResponse_Fork)(nil),    // 19: proto.StatusResponse.Fork
+	(*StatusResponse_Syncing)(nil), // 20: proto.StatusResponse.Syncing
+	(*PprofResponse_Open)(nil),     // 21: proto.PprofResponse.Open
+	(*PprofResponse_Input)(nil),    // 22: proto.PprofResponse.Input
+	nil,                            // 23: proto.PprofResponse.Open.HeadersEntry
+	(*emptypb.Empty)(nil),          // 24: google.protobuf.Empty
 }
 var file_command_server_proto_server_proto_depIdxs = []int32{
-	9,  // 0: proto.PeersListResponse.peers:type_name -> proto.Peer
-	9,  // 1: proto.PeersStatusResponse.peer:type_name -> proto.Peer
-	13, // 2: proto.StatusResponse.currentBlock:type_name -> proto.Header
-	13, // 3: proto.StatusResponse.currentHeader:type_name -> proto.Header
-	17, // 4: proto.StatusResponse.syncing:type_name -> proto.StatusResponse.Syncing
-	16, // 5: proto.StatusResponse.forks:type_name -> proto.StatusResponse.Fork
-	0,  // 6: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type
-	18, // 7: proto.PprofResponse.open:type_name -> proto.PprofResponse.Open
-	19, // 8: proto.PprofResponse.input:type_name -> proto.PprofResponse.Input
-	21, // 9: proto.PprofResponse.eof:type_name -> google.protobuf.Empty
-	20, // 10: proto.PprofResponse.Open.headers:type_name -> proto.PprofResponse.Open.HeadersEntry
-	14, // 11: proto.Bor.Pprof:input_type -> proto.PprofRequest
-	1,  // 12: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest
-	3,  // 13: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest
-	5,  // 14: proto.Bor.PeersList:input_type -> proto.PeersListRequest
-	7,  // 15: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest
-	10, // 16: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest
-	21, // 17: proto.Bor.Status:input_type -> google.protobuf.Empty
-	15, // 18: proto.Bor.Pprof:output_type -> proto.PprofResponse
-	2,  // 19: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse
-	4,  // 20: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse
-	6,  // 21: proto.Bor.PeersList:output_type -> proto.PeersListResponse
-	8,  // 22: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse
-	11, // 23: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse
-	12, // 24: proto.Bor.Status:output_type -> proto.StatusResponse
-	18, // [18:25] is the sub-list for method output_type
-	11, // [11:18] is the sub-list for method input_type
-	11, // [11:11] is the sub-list for extension type_name
-	11, // [11:11] is the sub-list for extension extendee
-	0,  // [0:11] is the sub-list for field type_name
+	3,  // 0: proto.ChainWatchResponse.oldchain:type_name -> proto.BlockStub
+	3,  // 1: proto.ChainWatchResponse.newchain:type_name -> proto.BlockStub
+	12, // 2: proto.PeersListResponse.peers:type_name -> proto.Peer
+	12, // 3: proto.PeersStatusResponse.peer:type_name -> proto.Peer
+	16, // 4: proto.StatusResponse.currentBlock:type_name -> proto.Header
+	16, // 5: proto.StatusResponse.currentHeader:type_name -> proto.Header
+	20, // 6: proto.StatusResponse.syncing:type_name -> proto.StatusResponse.Syncing
+	19, // 7: proto.StatusResponse.forks:type_name -> proto.StatusResponse.Fork
+	0,  // 8: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type
+	21, // 9: proto.PprofResponse.open:type_name -> proto.PprofResponse.Open
+	22, // 10: proto.PprofResponse.input:type_name -> proto.PprofResponse.Input
+	24, // 11: proto.PprofResponse.eof:type_name -> google.protobuf.Empty
+	23, // 12: proto.PprofResponse.Open.headers:type_name -> proto.PprofResponse.Open.HeadersEntry
+	17, // 13: proto.Bor.Pprof:input_type -> proto.PprofRequest
+	4,  // 14: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest
+	6,  // 15: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest
+	8,  // 16: proto.Bor.PeersList:input_type -> proto.PeersListRequest
+	10, // 17: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest
+	13, // 18: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest
+	24, // 19: proto.Bor.Status:input_type -> google.protobuf.Empty
+	1,  // 20: proto.Bor.ChainWatch:input_type -> proto.ChainWatchRequest
+	18, // 21: proto.Bor.Pprof:output_type -> proto.PprofResponse
+	5,  // 22: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse
+	7,  // 23: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse
+	9,  // 24: proto.Bor.PeersList:output_type -> proto.PeersListResponse
+	11, // 25: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse
+	14, // 26: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse
+	15, // 27: proto.Bor.Status:output_type -> proto.StatusResponse
+	2,  // 28: proto.Bor.ChainWatch:output_type -> proto.ChainWatchResponse
+	21, // [21:29] is the sub-list for method output_type
+	13, // [13:21] is the sub-list for method input_type
+	13, // [13:13] is the sub-list for extension type_name
+	13, // [13:13] is the sub-list for extension extendee
+	0,  // [0:13] is the sub-list for field type_name
 }
 
 func init() { file_command_server_proto_server_proto_init() }
@@ -1368,7 +1548,7 @@ func file_command_server_proto_server_proto_init() {
 	}
 	if !protoimpl.UnsafeEnabled {
 		file_command_server_proto_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersAddRequest); i {
+			switch v := v.(*ChainWatchRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1380,7 +1560,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersAddResponse); i {
+			switch v := v.(*ChainWatchResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1392,7 +1572,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersRemoveRequest); i {
+			switch v := v.(*BlockStub); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1404,7 +1584,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersRemoveResponse); i {
+			switch v := v.(*PeersAddRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1416,7 +1596,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersListRequest); i {
+			switch v := v.(*PeersAddResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1428,7 +1608,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersListResponse); i {
+			switch v := v.(*PeersRemoveRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1440,7 +1620,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersStatusRequest); i {
+			switch v := v.(*PeersRemoveResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1452,7 +1632,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PeersStatusResponse); i {
+			switch v := v.(*PeersListRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1464,7 +1644,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Peer); i {
+			switch v := v.(*PeersListResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1476,7 +1656,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ChainSetHeadRequest); i {
+			switch v := v.(*PeersStatusRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1488,7 +1668,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ChainSetHeadResponse); i {
+			switch v := v.(*PeersStatusResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1500,7 +1680,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*StatusResponse); i {
+			switch v := v.(*Peer); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1512,7 +1692,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Header); i {
+			switch v := v.(*ChainSetHeadRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1524,7 +1704,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PprofRequest); i {
+			switch v := v.(*ChainSetHeadResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1536,7 +1716,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PprofResponse); i {
+			switch v := v.(*StatusResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1548,7 +1728,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*StatusResponse_Fork); i {
+			switch v := v.(*Header); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1560,7 +1740,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*StatusResponse_Syncing); i {
+			switch v := v.(*PprofRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1572,7 +1752,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PprofResponse_Open); i {
+			switch v := v.(*PprofResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1584,6 +1764,42 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 		file_command_server_proto_server_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*StatusResponse_Fork); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_command_server_proto_server_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*StatusResponse_Syncing); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_command_server_proto_server_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PprofResponse_Open); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_command_server_proto_server_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PprofResponse_Input); i {
 			case 0:
 				return &v.state
@@ -1596,7 +1812,7 @@ func file_command_server_proto_server_proto_init() {
 			}
 		}
 	}
-	file_command_server_proto_server_proto_msgTypes[14].OneofWrappers = []interface{}{
+	file_command_server_proto_server_proto_msgTypes[17].OneofWrappers = []interface{}{
 		(*PprofResponse_Open_)(nil),
 		(*PprofResponse_Input_)(nil),
 		(*PprofResponse_Eof)(nil),
@@ -1607,7 +1823,7 @@ func file_command_server_proto_server_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_command_server_proto_server_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   20,
+			NumMessages:   23,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto
index de4fb13dd403ee89201b59fac0579e2ed21fd30a..2dc84bff78f3520a59002e9beea33fb7be5b8eef 100644
--- a/command/server/proto/server.proto
+++ b/command/server/proto/server.proto
@@ -20,8 +20,24 @@ service Bor {
     rpc ChainSetHead(ChainSetHeadRequest) returns (ChainSetHeadResponse);
 
     rpc Status(google.protobuf.Empty) returns (StatusResponse);
+    
+    rpc ChainWatch(ChainWatchRequest) returns (stream ChainWatchResponse);
 }
 
+message ChainWatchRequest {
+
+}
+
+message ChainWatchResponse {
+    repeated BlockStub oldchain = 1;
+    repeated BlockStub newchain = 2;
+    string type = 3;
+}
+
+message BlockStub {
+    string hash = 1;
+    uint64 number = 2;
+}
 
 message PeersAddRequest {
     string enode = 1;
diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go
index 7c2540d772fc741e401c622cad6099e1767fc8e5..9ed2593e4793fdecbc72bac1a75484f10e1ae664 100644
--- a/command/server/proto/server_grpc.pb.go
+++ b/command/server/proto/server_grpc.pb.go
@@ -1,13 +1,17 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.17.3
+// source: command/server/proto/server.proto
 
 package proto
 
 import (
 	context "context"
-	empty "github.com/golang/protobuf/ptypes/empty"
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -25,7 +29,8 @@ type BorClient interface {
 	PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error)
 	PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error)
 	ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error)
-	Status(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*StatusResponse, error)
+	Status(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*StatusResponse, error)
+	ChainWatch(ctx context.Context, in *ChainWatchRequest, opts ...grpc.CallOption) (Bor_ChainWatchClient, error)
 }
 
 type borClient struct {
@@ -113,7 +118,7 @@ func (c *borClient) ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, o
 	return out, nil
 }
 
-func (c *borClient) Status(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*StatusResponse, error) {
+func (c *borClient) Status(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*StatusResponse, error) {
 	out := new(StatusResponse)
 	err := c.cc.Invoke(ctx, "/proto.Bor/Status", in, out, opts...)
 	if err != nil {
@@ -122,6 +127,38 @@ func (c *borClient) Status(ctx context.Context, in *empty.Empty, opts ...grpc.Ca
 	return out, nil
 }
 
+func (c *borClient) ChainWatch(ctx context.Context, in *ChainWatchRequest, opts ...grpc.CallOption) (Bor_ChainWatchClient, error) {
+	stream, err := c.cc.NewStream(ctx, &Bor_ServiceDesc.Streams[1], "/proto.Bor/ChainWatch", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &borChainWatchClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type Bor_ChainWatchClient interface {
+	Recv() (*ChainWatchResponse, error)
+	grpc.ClientStream
+}
+
+type borChainWatchClient struct {
+	grpc.ClientStream
+}
+
+func (x *borChainWatchClient) Recv() (*ChainWatchResponse, error) {
+	m := new(ChainWatchResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
 // BorServer is the server API for Bor service.
 // All implementations must embed UnimplementedBorServer
 // for forward compatibility
@@ -132,7 +169,8 @@ type BorServer interface {
 	PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error)
 	PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error)
 	ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error)
-	Status(context.Context, *empty.Empty) (*StatusResponse, error)
+	Status(context.Context, *emptypb.Empty) (*StatusResponse, error)
+	ChainWatch(*ChainWatchRequest, Bor_ChainWatchServer) error
 	mustEmbedUnimplementedBorServer()
 }
 
@@ -158,9 +196,12 @@ func (UnimplementedBorServer) PeersStatus(context.Context, *PeersStatusRequest)
 func (UnimplementedBorServer) ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method ChainSetHead not implemented")
 }
-func (UnimplementedBorServer) Status(context.Context, *empty.Empty) (*StatusResponse, error) {
+func (UnimplementedBorServer) Status(context.Context, *emptypb.Empty) (*StatusResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
 }
+func (UnimplementedBorServer) ChainWatch(*ChainWatchRequest, Bor_ChainWatchServer) error {
+	return status.Errorf(codes.Unimplemented, "method ChainWatch not implemented")
+}
 func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {}
 
 // UnsafeBorServer may be embedded to opt out of forward compatibility for this service.
@@ -286,7 +327,7 @@ func _Bor_ChainSetHead_Handler(srv interface{}, ctx context.Context, dec func(in
 }
 
 func _Bor_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(empty.Empty)
+	in := new(emptypb.Empty)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
@@ -298,11 +339,32 @@ func _Bor_Status_Handler(srv interface{}, ctx context.Context, dec func(interfac
 		FullMethod: "/proto.Bor/Status",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BorServer).Status(ctx, req.(*empty.Empty))
+		return srv.(BorServer).Status(ctx, req.(*emptypb.Empty))
 	}
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Bor_ChainWatch_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(ChainWatchRequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(BorServer).ChainWatch(m, &borChainWatchServer{stream})
+}
+
+type Bor_ChainWatchServer interface {
+	Send(*ChainWatchResponse) error
+	grpc.ServerStream
+}
+
+type borChainWatchServer struct {
+	grpc.ServerStream
+}
+
+func (x *borChainWatchServer) Send(m *ChainWatchResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
 // Bor_ServiceDesc is the grpc.ServiceDesc for Bor service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -341,6 +403,11 @@ var Bor_ServiceDesc = grpc.ServiceDesc{
 			Handler:       _Bor_Pprof_Handler,
 			ServerStreams: true,
 		},
+		{
+			StreamName:    "ChainWatch",
+			Handler:       _Bor_ChainWatch_Handler,
+			ServerStreams: true,
+		},
 	},
 	Metadata: "command/server/proto/server.proto",
 }
diff --git a/command/server/service.go b/command/server/service.go
index fe70029aa9741b1eb4b520de3d037ba94a3f61fe..83692693ee43af283b322ca6477db96c30090f29 100644
--- a/command/server/service.go
+++ b/command/server/service.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/ethereum/go-ethereum/command/server/pprof"
 	"github.com/ethereum/go-ethereum/command/server/proto"
+	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/p2p/enode"
@@ -218,3 +219,39 @@ func gatherForks(configList ...interface{}) []*proto.StatusResponse_Fork {
 	}
 	return forks
 }
+
+func convertBlockToBlockStub(blocks []*types.Block) []*proto.BlockStub {
+
+	var blockStubs []*proto.BlockStub
+
+	for _, block := range blocks {
+		blockStub := &proto.BlockStub{
+			Hash:   block.Hash().String(),
+			Number: block.NumberU64(),
+		}
+		blockStubs = append(blockStubs, blockStub)
+	}
+
+	return blockStubs
+}
+
+func (s *Server) ChainWatch(req *proto.ChainWatchRequest, reply proto.Bor_ChainWatchServer) error {
+
+	chain2HeadChanSize := 10
+
+	chain2HeadCh := make(chan core.Chain2HeadEvent, chain2HeadChanSize)
+	headSub := s.backend.APIBackend.SubscribeChain2HeadEvent(chain2HeadCh)
+	defer headSub.Unsubscribe()
+
+	for {
+		msg := <-chain2HeadCh
+
+		err := reply.Send(&proto.ChainWatchResponse{Type: msg.Type,
+			Newchain: convertBlockToBlockStub(msg.NewChain),
+			Oldchain: convertBlockToBlockStub(msg.OldChain),
+		})
+		if err != nil {
+			return err
+		}
+	}
+}
diff --git a/core/blockchain.go b/core/blockchain.go
index 05108a9c6bbdd31dc1fe326eefe9c5eeb5531825..5bd2f9356145f367bc4910290146673519bdd619 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -217,6 +217,7 @@ type BlockChain struct {
 	borReceiptsCache *lru.Cache             // Cache for the most recent bor receipt receipts per block
 	stateSyncData    []*types.StateSyncData // State sync data
 	stateSyncFeed    event.Feed             // State sync feed
+	chain2HeadFeed   event.Feed             // Reorg/NewHead/Fork data feed
 }
 
 // NewBlockChain returns a fully initialised block chain using information
@@ -1640,10 +1641,21 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
 			for _, data := range bc.stateSyncData {
 				bc.stateSyncFeed.Send(StateSyncEvent{Data: data})
 			}
+
+			bc.chain2HeadFeed.Send(Chain2HeadEvent{
+				Type:     Chain2HeadCanonicalEvent,
+				NewChain: []*types.Block{block},
+			})
+
 			// BOR
 		}
 	} else {
 		bc.chainSideFeed.Send(ChainSideEvent{Block: block})
+
+		bc.chain2HeadFeed.Send(Chain2HeadEvent{
+			Type:     Chain2HeadForkEvent,
+			NewChain: []*types.Block{block},
+		})
 	}
 	return status, nil
 }
@@ -1737,6 +1749,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
 	defer func() {
 		if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
 			bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon})
+
+			bc.chain2HeadFeed.Send(Chain2HeadEvent{
+				Type:     Chain2HeadCanonicalEvent,
+				NewChain: []*types.Block{lastCanon},
+			})
 		}
 	}()
 	// Start the parallel header verifier
@@ -2262,6 +2279,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
 	}
 	// Ensure the user sees large reorgs
 	if len(oldChain) > 0 && len(newChain) > 0 {
+
+		bc.chain2HeadFeed.Send(Chain2HeadEvent{
+			Type:     Chain2HeadReorgEvent,
+			NewChain: newChain,
+			OldChain: oldChain,
+		})
+
 		logFn := log.Info
 		msg := "Chain reorg detected"
 		if len(oldChain) > 63 {
@@ -2570,6 +2594,11 @@ func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Su
 	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
 }
 
+// SubscribeChain2HeadEvent registers a subscription of ChainHeadEvent. ()
+func (bc *BlockChain) SubscribeChain2HeadEvent(ch chan<- Chain2HeadEvent) event.Subscription {
+	return bc.scope.Track(bc.chain2HeadFeed.Subscribe(ch))
+}
+
 // SubscribeChainSideEvent registers a subscription of ChainSideEvent.
 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
 	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
diff --git a/core/bor_events.go b/core/bor_events.go
index d8a5b38d0e9d1ada4a01dc4a9c3e6b02362d10ea..68f916fe791cb09274eff1b84553d950247a2b03 100644
--- a/core/bor_events.go
+++ b/core/bor_events.go
@@ -8,3 +8,16 @@ import (
 type StateSyncEvent struct {
 	Data *types.StateSyncData
 }
+
+var (
+	Chain2HeadReorgEvent     = "reorg"
+	Chain2HeadCanonicalEvent = "head"
+	Chain2HeadForkEvent      = "fork"
+)
+
+// For tracking reorgs related information
+type Chain2HeadEvent struct {
+	NewChain []*types.Block
+	OldChain []*types.Block
+	Type     string
+}
diff --git a/docs/cli/README.md b/docs/cli/README.md
index 74a6df2ca098c43e4534d0c4bd580db766a9a053..ed8a3f5977c32546fb8bbf40055f07f8c22ba0ad 100644
--- a/docs/cli/README.md
+++ b/docs/cli/README.md
@@ -31,4 +31,6 @@
 
 - [```status```](./status.md)
 
+- [```chain watch```](./chain_watch.md)
+
 - [```version```](./version.md)
diff --git a/docs/cli/chain_watch.md b/docs/cli/chain_watch.md
new file mode 100644
index 0000000000000000000000000000000000000000..4844bb7618d58631f8a1b383f1258ab3b0207eb6
--- /dev/null
+++ b/docs/cli/chain_watch.md
@@ -0,0 +1,3 @@
+# Chain watch
+
+The ```chain watch``` command is used to view the chainHead, reorg and fork events in real-time.
diff --git a/eth/bor_api_backend.go b/eth/bor_api_backend.go
index a6ff090c3f31760fcadc2666b67ae614be7da4d4..bbfc38518574bcc19951165ca696f6a9e8a677e1 100644
--- a/eth/bor_api_backend.go
+++ b/eth/bor_api_backend.go
@@ -67,3 +67,8 @@ func (b *EthAPIBackend) GetBorBlockTransactionWithBlockHash(ctx context.Context,
 func (b *EthAPIBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
 	return b.eth.BlockChain().SubscribeStateSyncEvent(ch)
 }
+
+// SubscribeChain2HeadEvent subscribes to reorg/head/fork event
+func (b *EthAPIBackend) SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription {
+	return b.eth.BlockChain().SubscribeChain2HeadEvent(ch)
+}
diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go
index 55c0c880f33c98a2c718081399ff4008929ff7f3..e699846b76572fd70743c884ce604944cf52d2fa 100644
--- a/ethstats/ethstats.go
+++ b/ethstats/ethstats.go
@@ -57,6 +57,9 @@ const (
 	txChanSize = 4096
 	// chainHeadChanSize is the size of channel listening to ChainHeadEvent.
 	chainHeadChanSize = 10
+
+	// chain2HeadChanSize is the size of channel listening to Chain2HeadEvent.
+	chain2HeadChanSize = 10
 )
 
 // backend encompasses the bare-minimum functionality needed for ethstats reporting
@@ -68,6 +71,9 @@ type backend interface {
 	GetTd(ctx context.Context, hash common.Hash) *big.Int
 	Stats() (pending int, queued int)
 	SyncProgress() ethereum.SyncProgress
+
+	// Bor
+	SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription
 }
 
 // fullNodeBackend encompasses the functionality necessary for a full node
@@ -96,6 +102,9 @@ type Service struct {
 
 	headSub event.Subscription
 	txSub   event.Subscription
+
+	//bor related sub
+	chain2headSub event.Subscription
 }
 
 // connWrapper is a wrapper to prevent concurrent-write or concurrent-read on the
@@ -195,7 +204,9 @@ func (s *Service) Start() error {
 	s.headSub = s.backend.SubscribeChainHeadEvent(chainHeadCh)
 	txEventCh := make(chan core.NewTxsEvent, txChanSize)
 	s.txSub = s.backend.SubscribeNewTxsEvent(txEventCh)
-	go s.loop(chainHeadCh, txEventCh)
+	chain2HeadCh := make(chan core.Chain2HeadEvent, chain2HeadChanSize)
+	s.chain2headSub = s.backend.SubscribeChain2HeadEvent(chain2HeadCh)
+	go s.loop(chainHeadCh, chain2HeadCh, txEventCh)
 
 	log.Info("Stats daemon started")
 	return nil
@@ -211,12 +222,13 @@ func (s *Service) Stop() error {
 
 // loop keeps trying to connect to the netstats server, reporting chain events
 // until termination.
-func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core.NewTxsEvent) {
+func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, chain2HeadCh chan core.Chain2HeadEvent, txEventCh chan core.NewTxsEvent) {
 	// Start a goroutine that exhausts the subscriptions to avoid events piling up
 	var (
-		quitCh = make(chan struct{})
-		headCh = make(chan *types.Block, 1)
-		txCh   = make(chan struct{}, 1)
+		quitCh  = make(chan struct{})
+		headCh  = make(chan *types.Block, 1)
+		txCh    = make(chan struct{}, 1)
+		head2Ch = make(chan core.Chain2HeadEvent, 100)
 	)
 	go func() {
 		var lastTx mclock.AbsTime
@@ -231,6 +243,13 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core
 				default:
 				}
 
+			// Notify of chain2head events, but drop if too frequent
+			case chain2head := <-chain2HeadCh:
+				select {
+				case head2Ch <- chain2head:
+				default:
+				}
+
 			// Notify of new transaction events, but drop if too frequent
 			case <-txEventCh:
 				if time.Duration(mclock.Now()-lastTx) < time.Second {
@@ -333,6 +352,12 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core
 					if err = s.reportPending(conn); err != nil {
 						log.Warn("Post-block transaction stats report failed", "err", err)
 					}
+
+				case chain2head := <-head2Ch:
+					if err = s.reportChain2Head(conn, &chain2head); err != nil {
+						log.Warn("Reorg stats report failed", "err", err)
+					}
+
 				case <-txCh:
 					if err = s.reportPending(conn); err != nil {
 						log.Warn("Transaction stats report failed", "err", err)
@@ -750,6 +775,49 @@ func (s *Service) reportPending(conn *connWrapper) error {
 	return conn.WriteJSON(report)
 }
 
+type blockStub struct {
+	Hash       string `json:"hash"`
+	Number     uint64 `json:"number"`
+	ParentHash string `json:"parent_hash"`
+}
+
+func createStub(b *types.Block) *blockStub {
+	s := &blockStub{
+		Hash:       b.Hash().String(),
+		ParentHash: b.ParentHash().String(),
+		Number:     b.NumberU64(),
+	}
+	return s
+}
+
+type ChainHeadEvent struct {
+	NewChain []*blockStub `json:"added"`
+	OldChain []*blockStub `json:"removed"`
+	Type     string       `json:"type"`
+}
+
+// reportChain2Head checks for reorg and sends current head to stats server.
+func (s *Service) reportChain2Head(conn *connWrapper, chain2HeadData *core.Chain2HeadEvent) error {
+	chainHeadEvent := ChainHeadEvent{
+		Type: chain2HeadData.Type,
+	}
+	for _, block := range chain2HeadData.NewChain {
+		chainHeadEvent.NewChain = append(chainHeadEvent.NewChain, createStub(block))
+	}
+	for _, block := range chain2HeadData.OldChain {
+		chainHeadEvent.OldChain = append(chainHeadEvent.OldChain, createStub(block))
+	}
+
+	stats := map[string]interface{}{
+		"id":    s.node,
+		"event": chainHeadEvent,
+	}
+	report := map[string][]interface{}{
+		"emit": {"headEvent", stats},
+	}
+	return conn.WriteJSON(report)
+}
+
 // nodeStats is the information to report about the local node.
 type nodeStats struct {
 	Active   bool `json:"active"`
diff --git a/go.sum b/go.sum
index 4fc75e79b09c93496ee4b6e9e91f61ac50d122ce..a353c13b4b435fa4e45c23c42a404f07935bcc79 100644
--- a/go.sum
+++ b/go.sum
@@ -33,7 +33,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW
 github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
 github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
-github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
 github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
 github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index 40ac02fccd80bdd9c70050a80465c81ee10ad4ae..97ce7c24cf685cbbee2ad2b9c9467db79748c93a 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -98,6 +98,7 @@ type Backend interface {
 	GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error)
 	GetBorBlockTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
 	GetBorBlockTransactionWithBlockHash(ctx context.Context, txHash common.Hash, blockHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
+	SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription
 
 	ChainConfig() *params.ChainConfig
 	Engine() consensus.Engine
diff --git a/les/bor_api_backend.go b/les/bor_api_backend.go
index 248246810981480193b167306145613cad249773..3a68bc0ab2e74a843f2a00fe5357b672f706cccb 100644
--- a/les/bor_api_backend.go
+++ b/les/bor_api_backend.go
@@ -17,3 +17,8 @@ func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr uint64, end
 func (b *LesApiBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
 	return b.eth.blockchain.SubscribeStateSyncEvent(ch)
 }
+
+// SubscribeChain2HeadEvent subscribe head/fork/reorg events.
+func (b *LesApiBackend) SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription {
+	return b.eth.BlockChain().SubscribeChain2HeadEvent(ch)
+}
diff --git a/light/lightchain.go b/light/lightchain.go
index 92e0e6637f7523daee809ee4a2e4423303408be1..92fe897d75b17b443835e9c52a1147b077d6421a 100644
--- a/light/lightchain.go
+++ b/light/lightchain.go
@@ -72,6 +72,9 @@ type LightChain struct {
 	running          int32 // whether LightChain is running or stopped
 	procInterrupt    int32 // interrupts chain insert
 	disableCheckFreq int32 // disables header verification
+
+	// Bor
+	chain2HeadFeed event.Feed
 }
 
 // NewLightChain returns a fully initialised light chain using information
@@ -561,6 +564,11 @@ func (lc *LightChain) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
 	return lc.scope.Track(new(event.Feed).Subscribe(ch))
 }
 
+// SubscribeChain2HeadEvent registers a subscription of Reorg/head/fork events.
+func (lc *LightChain) SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription {
+	return lc.scope.Track(lc.chain2HeadFeed.Subscribe(ch))
+}
+
 // DisableCheckFreq disables header validation. This is used for ultralight mode.
 func (lc *LightChain) DisableCheckFreq() {
 	atomic.StoreInt32(&lc.disableCheckFreq, 1)