Merge branch 'master' of github.com:harmony-one/harmony into monitorScript

pull/1067/head
ak 6 years ago
commit 4f5439b332
  1. 173
      api/proto/message/message.pb.go
  2. 33
      api/proto/message/message.proto
  3. 5
      api/service/syncing/syncing.go
  4. 35
      cmd/harmony/main.go
  5. 31
      consensus/consensus.go
  6. 9
      consensus/consensus_service.go
  7. 335
      consensus/consensus_v2.go
  8. 18
      consensus/consensus_viewchange_msg.go
  9. 139
      consensus/view_change.go
  10. 2
      core/resharding.go
  11. 6
      drand/drand_leader.go
  12. 1
      drand/drand_leader_msg.go
  13. 2
      drand/drand_validator_msg.go
  14. 199
      internal/genesis/foundational.go
  15. 7
      internal/genesis/genesis.go
  16. 59
      internal/utils/passphrase.go
  17. 44
      internal/utils/passphrase_test.go
  18. 46
      internal/utils/testing/tempfile.go
  19. 3
      node/node.go
  20. 29
      node/node_handler.go
  21. 24
      node/node_newblock.go
  22. 1
      node/node_syncing.go
  23. 5
      node/service_setup.go
  24. 6
      p2p/p2p.go
  25. 197
      scripts/node.sh

@ -523,9 +523,10 @@ func (m *StakingRequest) GetNodeId() string {
type ConsensusRequest struct { type ConsensusRequest struct {
ViewId uint32 `protobuf:"varint,1,opt,name=view_id,json=viewId,proto3" json:"view_id,omitempty"` ViewId uint32 `protobuf:"varint,1,opt,name=view_id,json=viewId,proto3" json:"view_id,omitempty"`
BlockNum uint64 `protobuf:"varint,2,opt,name=block_num,json=blockNum,proto3" json:"block_num,omitempty"` BlockNum uint64 `protobuf:"varint,2,opt,name=block_num,json=blockNum,proto3" json:"block_num,omitempty"`
BlockHash []byte `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` ShardId uint32 `protobuf:"varint,3,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"`
SenderPubkey []byte `protobuf:"bytes,4,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"` BlockHash []byte `protobuf:"bytes,4,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"`
Payload []byte `protobuf:"bytes,5,opt,name=payload,proto3" json:"payload,omitempty"` SenderPubkey []byte `protobuf:"bytes,5,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"`
Payload []byte `protobuf:"bytes,6,opt,name=payload,proto3" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -570,6 +571,13 @@ func (m *ConsensusRequest) GetBlockNum() uint64 {
return 0 return 0
} }
func (m *ConsensusRequest) GetShardId() uint32 {
if m != nil {
return m.ShardId
}
return 0
}
func (m *ConsensusRequest) GetBlockHash() []byte { func (m *ConsensusRequest) GetBlockHash() []byte {
if m != nil { if m != nil {
return m.BlockHash return m.BlockHash
@ -592,9 +600,10 @@ func (m *ConsensusRequest) GetPayload() []byte {
} }
type DrandRequest struct { type DrandRequest struct {
SenderPubkey []byte `protobuf:"bytes,1,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"` ShardId uint32 `protobuf:"varint,1,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"`
BlockHash []byte `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` SenderPubkey []byte `protobuf:"bytes,2,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` BlockHash []byte `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"`
Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -625,6 +634,13 @@ func (m *DrandRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_DrandRequest proto.InternalMessageInfo var xxx_messageInfo_DrandRequest proto.InternalMessageInfo
func (m *DrandRequest) GetShardId() uint32 {
if m != nil {
return m.ShardId
}
return 0
}
func (m *DrandRequest) GetSenderPubkey() []byte { func (m *DrandRequest) GetSenderPubkey() []byte {
if m != nil { if m != nil {
return m.SenderPubkey return m.SenderPubkey
@ -649,17 +665,18 @@ func (m *DrandRequest) GetPayload() []byte {
type ViewChangeRequest struct { type ViewChangeRequest struct {
ViewId uint32 `protobuf:"varint,1,opt,name=view_id,json=viewId,proto3" json:"view_id,omitempty"` ViewId uint32 `protobuf:"varint,1,opt,name=view_id,json=viewId,proto3" json:"view_id,omitempty"`
BlockNum uint64 `protobuf:"varint,2,opt,name=block_num,json=blockNum,proto3" json:"block_num,omitempty"` BlockNum uint64 `protobuf:"varint,2,opt,name=block_num,json=blockNum,proto3" json:"block_num,omitempty"`
SenderPubkey []byte `protobuf:"bytes,3,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"` ShardId uint32 `protobuf:"varint,3,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"`
LeaderPubkey []byte `protobuf:"bytes,4,opt,name=leader_pubkey,json=leaderPubkey,proto3" json:"leader_pubkey,omitempty"` SenderPubkey []byte `protobuf:"bytes,4,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"`
Payload []byte `protobuf:"bytes,5,opt,name=payload,proto3" json:"payload,omitempty"` LeaderPubkey []byte `protobuf:"bytes,5,opt,name=leader_pubkey,json=leaderPubkey,proto3" json:"leader_pubkey,omitempty"`
ViewchangeSig []byte `protobuf:"bytes,6,opt,name=viewchange_sig,json=viewchangeSig,proto3" json:"viewchange_sig,omitempty"` Payload []byte `protobuf:"bytes,6,opt,name=payload,proto3" json:"payload,omitempty"`
ViewidSig []byte `protobuf:"bytes,7,opt,name=viewid_sig,json=viewidSig,proto3" json:"viewid_sig,omitempty"` ViewchangeSig []byte `protobuf:"bytes,7,opt,name=viewchange_sig,json=viewchangeSig,proto3" json:"viewchange_sig,omitempty"`
ViewidSig []byte `protobuf:"bytes,8,opt,name=viewid_sig,json=viewidSig,proto3" json:"viewid_sig,omitempty"`
// below is for newview message only // below is for newview message only
// only need 1 valid m1 type message which is in payload // only need 1 valid m1 type message which is in payload
M2Aggsigs []byte `protobuf:"bytes,8,opt,name=m2_aggsigs,json=m2Aggsigs,proto3" json:"m2_aggsigs,omitempty"` M2Aggsigs []byte `protobuf:"bytes,9,opt,name=m2_aggsigs,json=m2Aggsigs,proto3" json:"m2_aggsigs,omitempty"`
M2Bitmap []byte `protobuf:"bytes,9,opt,name=m2_bitmap,json=m2Bitmap,proto3" json:"m2_bitmap,omitempty"` M2Bitmap []byte `protobuf:"bytes,10,opt,name=m2_bitmap,json=m2Bitmap,proto3" json:"m2_bitmap,omitempty"`
M3Aggsigs []byte `protobuf:"bytes,10,opt,name=m3_aggsigs,json=m3Aggsigs,proto3" json:"m3_aggsigs,omitempty"` M3Aggsigs []byte `protobuf:"bytes,11,opt,name=m3_aggsigs,json=m3Aggsigs,proto3" json:"m3_aggsigs,omitempty"`
M3Bitmap []byte `protobuf:"bytes,11,opt,name=m3_bitmap,json=m3Bitmap,proto3" json:"m3_bitmap,omitempty"` M3Bitmap []byte `protobuf:"bytes,12,opt,name=m3_bitmap,json=m3Bitmap,proto3" json:"m3_bitmap,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -704,6 +721,13 @@ func (m *ViewChangeRequest) GetBlockNum() uint64 {
return 0 return 0
} }
func (m *ViewChangeRequest) GetShardId() uint32 {
if m != nil {
return m.ShardId
}
return 0
}
func (m *ViewChangeRequest) GetSenderPubkey() []byte { func (m *ViewChangeRequest) GetSenderPubkey() []byte {
if m != nil { if m != nil {
return m.SenderPubkey return m.SenderPubkey
@ -784,65 +808,66 @@ func init() {
func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) } func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) }
var fileDescriptor_33c57e4bae7b9afd = []byte{ var fileDescriptor_33c57e4bae7b9afd = []byte{
// 914 bytes of a gzipped FileDescriptorProto // 934 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcd, 0x8e, 0xe2, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xdf, 0x6e, 0xe2, 0x46,
0x10, 0xc7, 0x31, 0x30, 0x18, 0x97, 0x0d, 0xd3, 0xdb, 0x49, 0x76, 0x9d, 0xc9, 0x46, 0x19, 0xb1, 0x14, 0xc6, 0x31, 0x10, 0x0c, 0xc7, 0x86, 0xcc, 0x4e, 0xdb, 0x5d, 0x6f, 0xba, 0x55, 0x23, 0x56,
0x8a, 0x34, 0x5a, 0x29, 0xa3, 0x15, 0x1c, 0xa2, 0x48, 0xb9, 0x30, 0xa6, 0xb5, 0x58, 0x33, 0x63, 0x95, 0xa2, 0x95, 0x1a, 0xad, 0xe0, 0xa2, 0xaa, 0xd4, 0x1b, 0x02, 0xa3, 0xc4, 0x4a, 0x62, 0xe8,
0x48, 0x63, 0x76, 0x94, 0x93, 0x65, 0xa0, 0xc5, 0x58, 0x63, 0x6c, 0xe2, 0x36, 0xb3, 0xe2, 0x85, 0xe0, 0x6c, 0xd4, 0x2b, 0x6b, 0x82, 0x47, 0xc4, 0x0a, 0xd8, 0xd4, 0x63, 0xb2, 0xe2, 0x05, 0xda,
0x72, 0xc9, 0x3d, 0xe7, 0xe4, 0x79, 0xf2, 0x12, 0x51, 0xb7, 0x6d, 0xcc, 0xc7, 0x46, 0x91, 0x72, 0x87, 0xe9, 0x7d, 0xaf, 0xbb, 0x6f, 0x56, 0xcd, 0x8c, 0xc1, 0xfc, 0xd9, 0xaa, 0x37, 0x55, 0xef,
0xc8, 0x8d, 0xfa, 0x57, 0xfd, 0xaa, 0xab, 0xcb, 0x5d, 0x05, 0xb4, 0x56, 0x8c, 0x73, 0x7f, 0xc9, 0x38, 0xdf, 0x39, 0xbf, 0x99, 0x73, 0x3e, 0xcf, 0x0c, 0xd0, 0x9c, 0x73, 0x21, 0xd8, 0x94, 0x9f,
0xae, 0xd7, 0x49, 0x9c, 0xc6, 0x58, 0xcd, 0xcd, 0xce, 0xef, 0x35, 0x50, 0xef, 0xb3, 0xdf, 0xf8, 0x2f, 0xd2, 0x24, 0x4b, 0xb0, 0x99, 0x87, 0xed, 0x3f, 0x2b, 0x60, 0xde, 0xea, 0xdf, 0xf8, 0x07,
0x7b, 0x30, 0x38, 0x4b, 0x9e, 0x83, 0x39, 0xf3, 0xd2, 0xed, 0x9a, 0x99, 0xca, 0xa5, 0x72, 0xd5, 0xb0, 0x05, 0x4f, 0x9f, 0xa3, 0x09, 0x0f, 0xb2, 0xd5, 0x82, 0x3b, 0xc6, 0xa9, 0x71, 0xd6, 0xea,
0xee, 0x7e, 0x7e, 0x5d, 0xa0, 0x93, 0xcc, 0xe9, 0x6e, 0xd7, 0x8c, 0xea, 0xbc, 0x34, 0xf0, 0x15, 0x7c, 0x79, 0xbe, 0x46, 0xc7, 0x3a, 0xe9, 0xaf, 0x16, 0x9c, 0x5a, 0xa2, 0x08, 0xf0, 0x19, 0x54,
0xd4, 0x25, 0x50, 0x3d, 0x02, 0xf2, 0xc4, 0x12, 0x90, 0x11, 0xf8, 0x35, 0x68, 0x3c, 0x58, 0x46, 0x15, 0x50, 0xde, 0x03, 0xf2, 0x85, 0x15, 0xa0, 0x2a, 0xf0, 0x1b, 0x68, 0x88, 0x68, 0x1a, 0xb3,
0x7e, 0xba, 0x49, 0x98, 0x59, 0xbb, 0x54, 0xae, 0x0c, 0x5a, 0x0a, 0xb8, 0x07, 0x2a, 0x4f, 0xfd, 0x6c, 0x99, 0x72, 0xa7, 0x72, 0x6a, 0x9c, 0xd9, 0xb4, 0x10, 0x70, 0x17, 0x4c, 0x91, 0xb1, 0xa7,
0xa7, 0x20, 0x5a, 0x9a, 0xf5, 0x4b, 0xe5, 0x4a, 0xef, 0xbe, 0x2a, 0xcf, 0xce, 0x74, 0xca, 0x7e, 0x28, 0x9e, 0x3a, 0xd5, 0x53, 0xe3, 0xcc, 0xea, 0xbc, 0x2a, 0xf6, 0xd6, 0x3a, 0xe5, 0xbf, 0x2e,
0xd9, 0x30, 0x9e, 0x0e, 0x2b, 0xb4, 0x88, 0xc4, 0x3f, 0x80, 0x36, 0x8f, 0x23, 0xce, 0x22, 0xbe, 0xb9, 0xc8, 0xae, 0x4a, 0x74, 0x5d, 0x89, 0x7f, 0x84, 0xc6, 0x24, 0x89, 0x05, 0x8f, 0xc5, 0x52,
0xe1, 0xe6, 0x99, 0xc4, 0xbe, 0xdc, 0x61, 0x56, 0xe1, 0x29, 0xc1, 0x32, 0x1a, 0x7f, 0x07, 0x67, 0x38, 0x47, 0x0a, 0x7b, 0xbd, 0xc1, 0xfa, 0xeb, 0x4c, 0x01, 0x16, 0xd5, 0xf8, 0x7b, 0x38, 0x0a,
0x8b, 0xc4, 0x8f, 0x16, 0x66, 0x43, 0x62, 0x5f, 0xec, 0xb0, 0x81, 0x50, 0x4b, 0x24, 0x8b, 0xc2, 0x53, 0x16, 0x87, 0x4e, 0x4d, 0x61, 0x5f, 0x6d, 0xb0, 0x81, 0x54, 0x0b, 0x44, 0x57, 0xe1, 0x9f,
0x3f, 0x02, 0x3c, 0x07, 0xec, 0xe3, 0xfc, 0xd1, 0x8f, 0x96, 0xcc, 0x54, 0x25, 0x73, 0xb1, 0x63, 0x00, 0x9e, 0x23, 0xfe, 0x71, 0xf2, 0xc8, 0xe2, 0x29, 0x77, 0x4c, 0xc5, 0x9c, 0x6c, 0x98, 0x0f,
0x3e, 0x04, 0xec, 0xa3, 0x25, 0x5d, 0x25, 0xb8, 0x17, 0x8f, 0x6f, 0xe0, 0x3c, 0x8c, 0xd3, 0x94, 0x11, 0xff, 0xd8, 0x57, 0xa9, 0x02, 0xdc, 0xaa, 0xc7, 0x17, 0x70, 0x3c, 0x4b, 0xb2, 0x8c, 0xa7,
0x25, 0x5b, 0x2f, 0xc9, 0x02, 0xcc, 0xe6, 0xd1, 0x25, 0xef, 0x32, 0x7f, 0xc9, 0xb7, 0xc3, 0x03, 0xab, 0x20, 0xd5, 0x05, 0x4e, 0x7d, 0x6f, 0xc8, 0x1b, 0x9d, 0x2f, 0xf8, 0xd6, 0x6c, 0x47, 0xb9,
0xe5, 0x46, 0x03, 0x35, 0x67, 0x3b, 0x7f, 0x28, 0xd0, 0xa4, 0x8c, 0xaf, 0xc5, 0x65, 0xfe, 0x8f, 0x68, 0x80, 0x99, 0xb3, 0xed, 0xbf, 0x0c, 0xa8, 0x53, 0x2e, 0x16, 0x72, 0x98, 0xff, 0xe3, 0xcb,
0x2f, 0x47, 0x00, 0x95, 0xe5, 0x67, 0xc7, 0xca, 0x0f, 0xa8, 0x77, 0xcd, 0xd3, 0xfa, 0x33, 0xff, 0x11, 0x40, 0x45, 0xfb, 0x7a, 0x5b, 0xf5, 0x01, 0xad, 0x8e, 0x73, 0xd8, 0xbf, 0xce, 0x5f, 0x95,
0xb0, 0x42, 0xcf, 0xc3, 0x43, 0xe9, 0x06, 0xa0, 0x59, 0xe0, 0x9d, 0xf7, 0x70, 0x7e, 0x44, 0x60, 0xe8, 0xf1, 0x6c, 0x57, 0xba, 0x00, 0xa8, 0xaf, 0xf1, 0xf6, 0x25, 0x1c, 0xef, 0x11, 0xd8, 0x01,
0x13, 0xd4, 0x75, 0xe8, 0x6f, 0x59, 0xc2, 0xcd, 0xea, 0x65, 0xed, 0x4a, 0xa3, 0x85, 0x89, 0x2f, 0x73, 0x31, 0x63, 0x2b, 0x9e, 0x0a, 0xa7, 0x7c, 0x5a, 0x39, 0x6b, 0xd0, 0x75, 0x88, 0x4f, 0xa0,
0xa0, 0x39, 0xf3, 0x43, 0x3f, 0x9a, 0x33, 0x6e, 0xd6, 0xa4, 0x6b, 0x67, 0x77, 0x7e, 0x53, 0xa0, 0xfe, 0xc0, 0x66, 0x2c, 0x9e, 0x70, 0xe1, 0x54, 0x54, 0x6a, 0x13, 0xb7, 0xff, 0x30, 0xa0, 0xb5,
0x7d, 0xd8, 0x3b, 0xfc, 0x2e, 0xbf, 0x58, 0xd6, 0x89, 0xd7, 0xff, 0xd0, 0xe2, 0xeb, 0xbd, 0x0b, 0xeb, 0x1d, 0x7e, 0x9f, 0x0f, 0xa6, 0x9d, 0x78, 0xf3, 0x0f, 0x16, 0x9f, 0x6f, 0x0d, 0xf8, 0x2d,
0x7e, 0x03, 0xfa, 0x3a, 0x09, 0x9e, 0xfd, 0x94, 0x79, 0x4f, 0x6c, 0x2b, 0x3b, 0xa2, 0x51, 0xc8, 0x58, 0x8b, 0x34, 0x7a, 0x66, 0x19, 0x0f, 0x9e, 0xf8, 0x4a, 0x39, 0xd2, 0xa0, 0x90, 0x4b, 0xd7,
0xa5, 0x5b, 0xb6, 0xc5, 0x2f, 0xa1, 0xe1, 0xaf, 0xe2, 0x4d, 0x94, 0xca, 0x7b, 0xd7, 0x68, 0x6e, 0x7c, 0x85, 0x5f, 0x42, 0x8d, 0xcd, 0x93, 0x65, 0x9c, 0xa9, 0xb9, 0x2b, 0x34, 0x8f, 0xda, 0xe7,
0x75, 0xae, 0xa1, 0x2e, 0x7b, 0xa9, 0xc1, 0x19, 0x71, 0x5c, 0x42, 0x51, 0x05, 0x03, 0x34, 0x28, 0x50, 0x55, 0x5e, 0x36, 0xe0, 0x88, 0x78, 0x3e, 0xa1, 0xa8, 0x84, 0x01, 0x6a, 0x94, 0x8c, 0xef,
0x99, 0x4c, 0xef, 0x5c, 0xa4, 0xe0, 0x73, 0xd0, 0xc7, 0xb6, 0x75, 0xeb, 0x3d, 0xd8, 0x8e, 0x43, 0x6e, 0x7c, 0x64, 0xe0, 0x63, 0xb0, 0x46, 0x6e, 0xff, 0x3a, 0xb8, 0x77, 0x3d, 0x8f, 0x50, 0x54,
0x28, 0xaa, 0x76, 0x6e, 0xa1, 0x7d, 0xf8, 0x9a, 0xf1, 0x25, 0xe8, 0x69, 0xe2, 0x47, 0xdc, 0x9f, 0x6e, 0x5f, 0x43, 0x6b, 0xf7, 0x34, 0xe3, 0x53, 0xb0, 0xb2, 0x94, 0xc5, 0x82, 0x4d, 0xb2, 0x28,
0xa7, 0x41, 0x1c, 0xc9, 0x9a, 0x0d, 0xba, 0x2f, 0xe1, 0x57, 0xa0, 0x46, 0xf1, 0x82, 0x79, 0xc1, 0x89, 0x55, 0xcf, 0x36, 0xdd, 0x96, 0xf0, 0x2b, 0x30, 0xe3, 0x24, 0xe4, 0x41, 0x14, 0xe6, 0x8d,
0x22, 0x2f, 0xac, 0x21, 0x4c, 0x7b, 0xd1, 0xf9, 0x55, 0x01, 0x74, 0xfc, 0xc8, 0x45, 0xb4, 0x78, 0xd5, 0x64, 0xe8, 0x86, 0xed, 0x4f, 0x06, 0xa0, 0xfd, 0x43, 0x2e, 0xab, 0xe5, 0xc1, 0x93, 0xd5,
0x78, 0x22, 0x5a, 0xe4, 0x6a, 0xd1, 0x86, 0x30, 0xed, 0x05, 0xfe, 0x0a, 0xb4, 0x59, 0x18, 0xcf, 0x72, 0xad, 0x26, 0xad, 0xc9, 0xd0, 0x0d, 0xf1, 0xd7, 0xd0, 0x78, 0x98, 0x25, 0x93, 0xa7, 0x20,
0x9f, 0xbc, 0x68, 0xb3, 0x92, 0x89, 0xea, 0xb4, 0x29, 0x05, 0x67, 0xb3, 0xc2, 0x5f, 0x03, 0x64, 0x5e, 0xce, 0xd5, 0x42, 0x55, 0x5a, 0x57, 0x82, 0xb7, 0x9c, 0xe3, 0xd7, 0x50, 0x17, 0x8f, 0x2c,
0xce, 0x47, 0x9f, 0x3f, 0x16, 0xc3, 0x29, 0x95, 0xa1, 0xcf, 0x1f, 0xf1, 0x1b, 0x68, 0x71, 0x16, 0x0d, 0x25, 0x56, 0x51, 0x98, 0xa9, 0x62, 0x37, 0xc4, 0xdf, 0x00, 0x68, 0xee, 0x91, 0x89, 0x47,
0x2d, 0x58, 0xe2, 0xad, 0x37, 0x33, 0xd1, 0xa1, 0xba, 0x8c, 0x30, 0x32, 0x71, 0x2c, 0x35, 0xf9, 0x75, 0x37, 0x6d, 0xaa, 0x57, 0xba, 0x62, 0xe2, 0x11, 0xbf, 0x85, 0xa6, 0xe0, 0x71, 0xc8, 0xd3,
0xfd, 0xfc, 0x6d, 0x18, 0xfb, 0x0b, 0x39, 0x8a, 0x06, 0x2d, 0xcc, 0x4e, 0x08, 0xc6, 0xfe, 0x54, 0x60, 0xb1, 0x7c, 0x90, 0xe6, 0x1d, 0xa9, 0x0a, 0x5b, 0x8b, 0x23, 0xa5, 0xa9, 0x4f, 0xcb, 0x56,
0x9d, 0xa6, 0x53, 0x3e, 0x91, 0xee, 0xb0, 0xa4, 0xea, 0x71, 0x49, 0x7b, 0xa7, 0xd5, 0x0e, 0x4f, 0xb3, 0x84, 0xe9, 0xeb, 0x66, 0xd3, 0x75, 0xd8, 0xfe, 0xdd, 0x00, 0x7b, 0xfb, 0xc6, 0xed, 0x74,
0xfb, 0xab, 0x0a, 0x2f, 0x4e, 0x06, 0xf2, 0x3f, 0xf6, 0xe5, 0xa4, 0xd2, 0xda, 0x27, 0x2a, 0x7d, 0x62, 0xec, 0x76, 0x72, 0xb0, 0x55, 0xf9, 0x33, 0x5b, 0xed, 0xb6, 0x5b, 0xd9, 0x6f, 0x77, 0xab,
0x03, 0xad, 0x90, 0xf9, 0xa7, 0xdd, 0xc9, 0xc4, 0x7f, 0xeb, 0x0e, 0xfe, 0x16, 0xda, 0xe5, 0xaa, 0x93, 0xea, 0x6e, 0x27, 0xbf, 0x55, 0xe0, 0xc5, 0xc1, 0x3d, 0xfe, 0xef, 0xed, 0x3c, 0x18, 0xa2,
0xf0, 0x78, 0xb0, 0x94, 0x2b, 0xc9, 0xa0, 0xad, 0x52, 0x9d, 0x04, 0x4b, 0xd1, 0x0f, 0x21, 0x04, 0xfa, 0x99, 0x21, 0xde, 0x42, 0x73, 0xc6, 0xd9, 0xa1, 0xa9, 0x5a, 0xfc, 0x37, 0x53, 0xf1, 0x77,
0x0b, 0x19, 0xa2, 0x66, 0xfd, 0xc8, 0x94, 0xdc, 0xbd, 0xea, 0x7a, 0xfe, 0x72, 0xc9, 0x83, 0x25, 0xd0, 0x2a, 0x1e, 0x9f, 0x40, 0x44, 0x53, 0xf5, 0x60, 0xd9, 0xb4, 0x59, 0xa8, 0xe3, 0x68, 0x2a,
0x97, 0xdb, 0xc5, 0xa0, 0xda, 0xaa, 0xdb, 0xcf, 0x04, 0x71, 0xcb, 0x55, 0xd7, 0x9b, 0x05, 0xe9, 0xad, 0x92, 0x42, 0x14, 0xaa, 0x92, 0xba, 0xb6, 0x4a, 0x2b, 0x79, 0x7a, 0xde, 0x09, 0xd8, 0x74,
0xca, 0x5f, 0x9b, 0x9a, 0xf4, 0x36, 0x57, 0xdd, 0x1b, 0x69, 0x4b, 0xb6, 0xb7, 0x63, 0x21, 0x67, 0x2a, 0xa2, 0xa9, 0x70, 0x1a, 0x3a, 0x3d, 0xef, 0xf4, 0xb4, 0x20, 0x0d, 0x98, 0x77, 0x82, 0x87,
0x7b, 0xfb, 0x6c, 0xaf, 0x60, 0xf5, 0x9c, 0xed, 0x65, 0xec, 0xdb, 0x21, 0xe8, 0x7b, 0x1b, 0x06, 0x28, 0x9b, 0xb3, 0x85, 0x03, 0x2a, 0x5b, 0x9f, 0x77, 0x2e, 0x54, 0xac, 0xd8, 0xee, 0x86, 0xb5,
0xb7, 0x40, 0xb3, 0x46, 0xce, 0x84, 0x38, 0x93, 0xe9, 0x04, 0x55, 0xb0, 0x0e, 0xea, 0xc4, 0xed, 0x72, 0xb6, 0xbb, 0xcd, 0x76, 0xd7, 0xac, 0x9d, 0xb3, 0x5d, 0xcd, 0xbe, 0xbb, 0x02, 0x6b, 0xeb,
0xdf, 0xda, 0xce, 0x7b, 0xa4, 0x88, 0x21, 0x19, 0xd0, 0xbe, 0x33, 0x40, 0x55, 0x8c, 0xa1, 0x6d, 0xcd, 0xc2, 0x4d, 0x68, 0xf4, 0x87, 0xde, 0x98, 0x78, 0xe3, 0xbb, 0x31, 0x2a, 0x61, 0x0b, 0xcc,
0xdd, 0xd9, 0xc4, 0x71, 0xbd, 0xc9, 0x74, 0x3c, 0x1e, 0x51, 0x17, 0xd5, 0xde, 0xfe, 0xa9, 0x80, 0xb1, 0xdf, 0xbb, 0x76, 0xbd, 0x4b, 0x64, 0xc8, 0x6b, 0x37, 0xa0, 0x3d, 0x6f, 0x80, 0xca, 0x18,
0xbe, 0xb7, 0x7b, 0xf0, 0x05, 0xbc, 0x74, 0xc8, 0x83, 0x33, 0x1a, 0x10, 0xef, 0x86, 0xf4, 0xad, 0x43, 0xab, 0x7f, 0xe3, 0x12, 0xcf, 0x0f, 0xc6, 0x77, 0xa3, 0xd1, 0x90, 0xfa, 0xa8, 0xf2, 0xee,
0x91, 0xe3, 0x15, 0xa9, 0x2a, 0xd8, 0x80, 0x66, 0xdf, 0x71, 0x46, 0x53, 0xc7, 0x22, 0x48, 0x11, 0x93, 0x01, 0xd6, 0xd6, 0x6b, 0x86, 0x4f, 0xe0, 0xa5, 0x47, 0xee, 0xbd, 0xe1, 0x80, 0x04, 0x17,
0xa7, 0x8c, 0x29, 0x19, 0xf7, 0x29, 0x41, 0x55, 0xe1, 0xca, 0x8d, 0x01, 0xaa, 0x89, 0x69, 0xb4, 0xa4, 0xd7, 0x1f, 0x7a, 0xc1, 0x7a, 0xa9, 0x12, 0xb6, 0xa1, 0xde, 0xf3, 0xbc, 0xe1, 0x9d, 0xd7,
0x46, 0xf7, 0xf7, 0xb6, 0x8b, 0xea, 0x59, 0x6d, 0xe2, 0xb7, 0x4b, 0x06, 0xe8, 0x0c, 0xb7, 0x01, 0x27, 0xc8, 0x90, 0xbb, 0x8c, 0x28, 0x19, 0xf5, 0x28, 0x41, 0x65, 0x99, 0xca, 0x83, 0x01, 0xaa,
0x3e, 0xd8, 0xe4, 0xc1, 0x1a, 0xf6, 0x9d, 0xf7, 0x04, 0x35, 0x44, 0x16, 0x87, 0x3c, 0x08, 0x09, 0xc8, 0xfb, 0xdd, 0x1f, 0xde, 0xde, 0xba, 0x3e, 0xaa, 0xea, 0xde, 0xe4, 0x6f, 0x9f, 0x0c, 0xd0,
0xa9, 0xc2, 0x29, 0x6b, 0xf5, 0x6c, 0xc7, 0x76, 0x11, 0x60, 0x04, 0x46, 0x66, 0xe7, 0xd9, 0x74, 0x11, 0x6e, 0x01, 0x7c, 0x70, 0xc9, 0x7d, 0xff, 0xaa, 0xe7, 0x5d, 0x12, 0x54, 0x93, 0xab, 0x78,
0xfc, 0x19, 0x9c, 0xdf, 0x8d, 0x5c, 0x97, 0xd0, 0x9f, 0x3d, 0x4a, 0x7e, 0x9a, 0x92, 0x89, 0x8b, 0xe4, 0x5e, 0x4a, 0xc8, 0x94, 0x49, 0xd5, 0x6b, 0xe0, 0x7a, 0xae, 0x8f, 0x00, 0x23, 0xb0, 0x75,
0x8c, 0x6e, 0x1f, 0x5a, 0x56, 0x18, 0xb0, 0x28, 0xcd, 0x7b, 0x82, 0xdf, 0x81, 0x3a, 0x4e, 0xe2, 0x9c, 0xaf, 0x66, 0xe1, 0x2f, 0xe0, 0xf8, 0x66, 0xe8, 0xfb, 0x84, 0xfe, 0x12, 0x50, 0xf2, 0xf3,
0x39, 0xe3, 0x1c, 0xa3, 0xe3, 0x0d, 0x7b, 0xf1, 0x62, 0xa7, 0x14, 0x4b, 0xb0, 0x53, 0x99, 0x35, 0x1d, 0x19, 0xfb, 0xc8, 0xee, 0xf4, 0xa0, 0xd9, 0x9f, 0x45, 0x3c, 0xce, 0x72, 0x4f, 0xf0, 0x7b,
0xe4, 0xbf, 0x74, 0xef, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0x52, 0x45, 0x7b, 0xb6, 0x07, 0x30, 0x47, 0x69, 0x32, 0xe1, 0x42, 0x60, 0xb4, 0xff, 0x66, 0x9f, 0xbc, 0xd8, 0x28, 0xeb, 0x67,
0x00, 0x00, 0xb5, 0x5d, 0x7a, 0xa8, 0xa9, 0xff, 0xfd, 0xee, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x60,
0x9a, 0xe1, 0x08, 0x08, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

@ -82,31 +82,34 @@ message StakingRequest {
message ConsensusRequest { message ConsensusRequest {
uint32 view_id = 1; uint32 view_id = 1;
uint64 block_num = 2; uint64 block_num = 2;
bytes block_hash = 3; uint32 shard_id = 3;
bytes sender_pubkey = 4; bytes block_hash = 4;
bytes payload = 5; bytes sender_pubkey = 5;
bytes payload = 6;
} }
message DrandRequest { message DrandRequest {
bytes sender_pubkey = 1; uint32 shard_id = 1;
bytes block_hash = 2; bytes sender_pubkey = 2;
bytes payload = 3; bytes block_hash = 3;
bytes payload = 4;
} }
message ViewChangeRequest { message ViewChangeRequest {
uint32 view_id = 1; uint32 view_id = 1;
uint64 block_num = 2; uint64 block_num = 2;
bytes sender_pubkey = 3; uint32 shard_id = 3;
bytes leader_pubkey = 4; bytes sender_pubkey = 4;
bytes payload = 5; // message payload: either m1 type or m2 type bytes leader_pubkey = 5;
bytes viewchange_sig = 6; // signature on payload bytes payload = 6; // message payload: either m1 type or m2 type
bytes viewid_sig = 7; // signature on view_id bytes viewchange_sig = 7; // signature on payload
bytes viewid_sig = 8; // signature on view_id
// below is for newview message only // below is for newview message only
// only need 1 valid m1 type message which is in payload // only need 1 valid m1 type message which is in payload
bytes m2_aggsigs = 8; // m2: |nil| bytes m2_aggsigs = 9; // m2: |nil|
bytes m2_bitmap = 9; bytes m2_bitmap = 10;
bytes m3_aggsigs = 10; // m3: |viewID| bytes m3_aggsigs = 11; // m3: |viewID|
bytes m3_bitmap= 11; bytes m3_bitmap= 12;
} }

@ -476,6 +476,9 @@ func (ss *StateSync) updateBlockAndStatus(block *types.Block, bc *core.BlockChai
_, err := bc.InsertChain([]*types.Block{block}) _, err := bc.InsertChain([]*types.Block{block})
if err != nil { if err != nil {
utils.GetLogInstance().Debug("Error adding new block to blockchain", "Error", err) utils.GetLogInstance().Debug("Error adding new block to blockchain", "Error", err)
utils.GetLogInstance().Debug("Rolling back current block!", "block", bc.CurrentBlock())
bc.Rollback([]common.Hash{bc.CurrentBlock().Hash()})
return false return false
} }
ss.syncMux.Lock() ss.syncMux.Lock()
@ -633,7 +636,7 @@ func (ss *StateSync) IsSameBlockchainHeight(bc *core.BlockChain) (uint64, bool)
func (ss *StateSync) IsOutOfSync(bc *core.BlockChain) bool { func (ss *StateSync) IsOutOfSync(bc *core.BlockChain) bool {
otherHeight := ss.getMaxPeerHeight() otherHeight := ss.getMaxPeerHeight()
currentHeight := bc.CurrentBlock().NumberU64() currentHeight := bc.CurrentBlock().NumberU64()
utils.GetLogInstance().Debug("[SYNC] IsOutOfSync", "otherHeight", otherHeight, "myHeight", currentHeight) utils.GetLogInstance().Debug("[SYNC] Checking sync status", "OtherHeight", otherHeight, "MyHeight", currentHeight, "IsOutOfSync", currentHeight+inSyncThreshold < otherHeight)
return currentHeight+inSyncThreshold < otherHeight return currentHeight+inSyncThreshold < otherHeight
} }

@ -13,17 +13,17 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/accounts" "github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/accounts/keystore" "github.com/harmony-one/harmony/accounts/keystore"
"github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/drand"
"github.com/harmony-one/harmony/internal/common" "github.com/harmony-one/harmony/internal/common"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/genesis"
hmykey "github.com/harmony-one/harmony/internal/keystore" hmykey "github.com/harmony-one/harmony/internal/keystore"
memprofiling "github.com/harmony-one/harmony/internal/memprofiling" "github.com/harmony-one/harmony/internal/memprofiling"
"github.com/harmony-one/harmony/internal/profiler" "github.com/harmony-one/harmony/internal/profiler"
"github.com/harmony-one/harmony/internal/shardchain" "github.com/harmony-one/harmony/internal/shardchain"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
@ -110,6 +110,10 @@ var (
// -nopass is false by default. The keyfile must be encrypted. // -nopass is false by default. The keyfile must be encrypted.
hmyNoPass = flag.Bool("nopass", false, "No passphrase for the key (testing only)") hmyNoPass = flag.Bool("nopass", false, "No passphrase for the key (testing only)")
// -pass takes on "pass:password", "env:var", "file:pathname",
// "fd:number", or "stdin" form.
// See “PASS PHRASE ARGUMENTS” section of openssl(1) for details.
hmyPass = flag.String("pass", "", "how to get passphrase for the key")
stakingAccounts = flag.String("accounts", "", "account addresses of the node") stakingAccounts = flag.String("accounts", "", "account addresses of the node")
@ -170,7 +174,7 @@ func initSetup() {
accountIndex, genesisAccount = genesis.FindAccount(*stakingAccounts) accountIndex, genesisAccount = genesis.FindAccount(*stakingAccounts)
if genesisAccount == nil { if genesisAccount == nil {
fmt.Printf("Can't find the account address: %v!\n", *stakingAccounts) fmt.Printf("Can't find the account address: %v\n", *stakingAccounts)
os.Exit(100) os.Exit(100)
} }
@ -184,7 +188,7 @@ func initSetup() {
} }
if !foundAccount { if !foundAccount {
fmt.Printf("Can't find the matching account key: %v!\n", genesisAccount.Address) fmt.Printf("Can't find the matching account key: %v\n", genesisAccount.Address)
os.Exit(101) os.Exit(101)
} }
@ -196,7 +200,14 @@ func initSetup() {
var myPass string var myPass string
if !*hmyNoPass { if !*hmyNoPass {
myPass = utils.AskForPassphrase("Passphrase: ") if *hmyPass == "" {
myPass = utils.AskForPassphrase("Passphrase: ")
} else if pass, err := utils.GetPassphraseFromSource(*hmyPass); err != nil {
fmt.Printf("Cannot read passphrase: %s\n", err)
os.Exit(3)
} else {
myPass = pass
}
err := ks.Unlock(myAccount, myPass) err := ks.Unlock(myAccount, myPass)
if err != nil { if err != nil {
fmt.Printf("Wrong Passphrase! Unable to unlock account key!\n") fmt.Printf("Wrong Passphrase! Unable to unlock account key!\n")
@ -384,14 +395,12 @@ func setUpConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
currentNode.NodeConfig.ConsensusPubKey = nodeConfig.ConsensusPubKey currentNode.NodeConfig.ConsensusPubKey = nodeConfig.ConsensusPubKey
currentNode.NodeConfig.ConsensusPriKey = nodeConfig.ConsensusPriKey currentNode.NodeConfig.ConsensusPriKey = nodeConfig.ConsensusPriKey
// Add randomness protocol // TODO: Disable drand. Currently drand isn't functioning but we want to compeletely turn it off for full protection.
// TODO: enable drand only for beacon chain // Enable it back after mainnet.
// TODO: put this in a better place other than main. // dRand := drand.New(nodeConfig.Host, nodeConfig.ShardID, []p2p.Peer{}, nodeConfig.Leader, currentNode.ConfirmedBlockChannel, nodeConfig.ConsensusPriKey)
// TODO(minhdoan): During refactoring, found out that the peers list is actually empty. Need to clean up the logic of drand later. // currentNode.Consensus.RegisterPRndChannel(dRand.PRndChannel)
dRand := drand.New(nodeConfig.Host, nodeConfig.ShardID, []p2p.Peer{}, nodeConfig.Leader, currentNode.ConfirmedBlockChannel, nodeConfig.ConsensusPriKey) // currentNode.Consensus.RegisterRndChannel(dRand.RndChannel)
currentNode.Consensus.RegisterPRndChannel(dRand.PRndChannel) // currentNode.DRand = dRand
currentNode.Consensus.RegisterRndChannel(dRand.RndChannel)
currentNode.DRand = dRand
// This needs to be executed after consensus and drand are setup // This needs to be executed after consensus and drand are setup
if !*isNewNode || *shardID > -1 { // initial staking new node doesn't need to initialize shard state if !*isNewNode || *shardID > -1 { // initial staking new node doesn't need to initialize shard state

@ -45,6 +45,9 @@ type Consensus struct {
// How long to delay sending commit messages. // How long to delay sending commit messages.
delayCommit time.Duration delayCommit time.Duration
// Consensus rounds whose commit phase finished
commitFinishChan chan uint32
// 2 types of timeouts: normal and viewchange // 2 types of timeouts: normal and viewchange
consensusTimeout map[TimeoutType]*utils.Timeout consensusTimeout map[TimeoutType]*utils.Timeout
@ -140,6 +143,8 @@ type Consensus struct {
// Used to convey to the consensus main loop that block syncing has finished. // Used to convey to the consensus main loop that block syncing has finished.
syncReadyChan chan struct{} syncReadyChan chan struct{}
// Used to convey to the consensus main loop that node is out of sync
syncNotReadyChan chan struct{}
// If true, this consensus will not propose view change. // If true, this consensus will not propose view change.
disableViewChange bool disableViewChange bool
@ -179,6 +184,11 @@ func (consensus *Consensus) BlocksSynchronized() {
consensus.syncReadyChan <- struct{}{} consensus.syncReadyChan <- struct{}{}
} }
// BlocksNotSynchronized lets the main loop know that block is not synchronized
func (consensus *Consensus) BlocksNotSynchronized() {
consensus.syncNotReadyChan <- struct{}{}
}
// WaitForSyncing informs the node syncing service to start syncing // WaitForSyncing informs the node syncing service to start syncing
func (consensus *Consensus) WaitForSyncing() { func (consensus *Consensus) WaitForSyncing() {
<-consensus.blockNumLowChan <-consensus.blockNumLowChan
@ -189,6 +199,12 @@ func (consensus *Consensus) Quorum() int {
return len(consensus.PublicKeys)*2/3 + 1 return len(consensus.PublicKeys)*2/3 + 1
} }
// RewardThreshold returns the threshold to stop accepting commit messages
// when leader receives enough signatures for block reward
func (consensus *Consensus) RewardThreshold() int {
return len(consensus.PublicKeys) * 9 / 10
}
// StakeInfoFinder finds the staking account for the given consensus key. // StakeInfoFinder finds the staking account for the given consensus key.
type StakeInfoFinder interface { type StakeInfoFinder interface {
// FindStakeInfoByNodeKey returns a list of staking information matching // FindStakeInfoByNodeKey returns a list of staking information matching
@ -245,6 +261,8 @@ func New(host p2p.Host, ShardID uint32, leader p2p.Peer, blsPriKey *bls.SecretKe
consensus.MsgChan = make(chan []byte) consensus.MsgChan = make(chan []byte)
consensus.syncReadyChan = make(chan struct{}) consensus.syncReadyChan = make(chan struct{})
consensus.syncNotReadyChan = make(chan struct{})
consensus.commitFinishChan = make(chan uint32)
consensus.ReadySignal = make(chan struct{}) consensus.ReadySignal = make(chan struct{})
if nodeconfig.GetDefaultConfig().IsLeader() { if nodeconfig.GetDefaultConfig().IsLeader() {
@ -318,6 +336,7 @@ func accumulateRewards(
} }
totalAmount := big.NewInt(0) totalAmount := big.NewInt(0)
numAccounts := 0 numAccounts := 0
signers := []string{}
for idx, member := range parentCommittee.NodeList { for idx, member := range parentCommittee.NodeList {
if signed, err := mask.IndexEnabled(idx); err != nil { if signed, err := mask.IndexEnabled(idx); err != nil {
return ctxerror.New("cannot check for committer bit", return ctxerror.New("cannot check for committer bit",
@ -328,16 +347,14 @@ func accumulateRewards(
} }
numAccounts++ numAccounts++
account := member.EcdsaAddress account := member.EcdsaAddress
getLogger().Info("rewarding block signer", signers = append(signers, account.Hex())
"account", account,
"node", member.BlsPublicKey.Hex(),
"amount", BlockReward)
state.AddBalance(account, BlockReward) state.AddBalance(account, BlockReward)
totalAmount = new(big.Int).Add(totalAmount, BlockReward) totalAmount = new(big.Int).Add(totalAmount, BlockReward)
} }
getLogger().Debug("paid out block reward", getLogger().Debug("【Block Reward] Successfully paid out block reward",
"numAccounts", numAccounts, "NumAccounts", numAccounts,
"totalAmount", totalAmount) "TotalAmount", totalAmount,
"Signers", signers)
return nil return nil
} }

@ -101,6 +101,7 @@ func (consensus *Consensus) Prepare(chain consensus_engine.ChainReader, header *
func (consensus *Consensus) populateMessageFields(request *msg_pb.ConsensusRequest) { func (consensus *Consensus) populateMessageFields(request *msg_pb.ConsensusRequest) {
request.ViewId = consensus.viewID request.ViewId = consensus.viewID
request.BlockNum = consensus.blockNum request.BlockNum = consensus.blockNum
request.ShardId = consensus.ShardID
// 32 byte block hash // 32 byte block hash
request.BlockHash = consensus.blockHash[:] request.BlockHash = consensus.blockHash[:]
@ -169,7 +170,9 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls.PublicKey) int {
consensus.pubKeyLock.Lock() consensus.pubKeyLock.Lock()
consensus.PublicKeys = append(pubKeys[:0:0], pubKeys...) consensus.PublicKeys = append(pubKeys[:0:0], pubKeys...)
consensus.CommitteePublicKeys = map[string]bool{} consensus.CommitteePublicKeys = map[string]bool{}
utils.GetLogInstance().Info("My Committee")
for _, pubKey := range consensus.PublicKeys { for _, pubKey := range consensus.PublicKeys {
utils.GetLogInstance().Info("Member", "BlsPubKey", pubKey.SerializeToHexStr())
consensus.CommitteePublicKeys[pubKey.SerializeToHexStr()] = true consensus.CommitteePublicKeys[pubKey.SerializeToHexStr()] = true
} }
// TODO: use pubkey to identify leader rather than p2p.Peer. // TODO: use pubkey to identify leader rather than p2p.Peer.
@ -186,7 +189,6 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls.PublicKey) int {
} }
utils.GetLogInstance().Info("My Leader", "info", consensus.LeaderPubKey.SerializeToHexStr()) utils.GetLogInstance().Info("My Leader", "info", consensus.LeaderPubKey.SerializeToHexStr())
utils.GetLogInstance().Info("My Committee", "info", consensus.PublicKeys)
consensus.pubKeyLock.Unlock() consensus.pubKeyLock.Unlock()
// reset states after update public keys // reset states after update public keys
consensus.ResetState() consensus.ResetState()
@ -326,7 +328,8 @@ func (consensus *Consensus) GetViewIDSigsArray() []*bls.Sign {
// ResetState resets the state of the consensus // ResetState resets the state of the consensus
func (consensus *Consensus) ResetState() { func (consensus *Consensus) ResetState() {
consensus.phase = Announce consensus.getLogger().Debug("[ResetState] Resetting consensus state", "Phase", consensus.phase)
consensus.switchPhase(Announce, true)
consensus.blockHash = [32]byte{} consensus.blockHash = [32]byte{}
consensus.prepareSigs = map[string]*bls.Sign{} consensus.prepareSigs = map[string]*bls.Sign{}
consensus.commitSigs = map[string]*bls.Sign{} consensus.commitSigs = map[string]*bls.Sign{}
@ -537,5 +540,5 @@ func (consensus *Consensus) logger(logger log.Logger) log.Logger {
// getLogger returns logger for consensus contexts added // getLogger returns logger for consensus contexts added
func (consensus *Consensus) getLogger() log.Logger { func (consensus *Consensus) getLogger() log.Logger {
logger := consensus.logger(utils.GetLogInstance()) logger := consensus.logger(utils.GetLogInstance())
return utils.WithCallerSkip(logger, 1) return logger
} }

@ -37,6 +37,20 @@ func (consensus *Consensus) handleMessageUpdate(payload []byte) {
return return
} }
if msg.Type == msg_pb.MessageType_VIEWCHANGE || msg.Type == msg_pb.MessageType_NEWVIEW {
if msg.GetViewchange() != nil && msg.GetViewchange().ShardId != consensus.ShardID {
consensus.getLogger().Warn("Received view change message from different shard",
"myShardId", consensus.ShardID, "receivedShardId", msg.GetViewchange().ShardId)
return
}
} else {
if msg.GetConsensus() != nil && msg.GetConsensus().ShardId != consensus.ShardID {
consensus.getLogger().Warn("Received consensus message from different shard",
"myShardId", consensus.ShardID, "receivedShardId", msg.GetConsensus().ShardId)
return
}
}
switch msg.Type { switch msg.Type {
case msg_pb.MessageType_ANNOUNCE: case msg_pb.MessageType_ANNOUNCE:
consensus.onAnnounce(msg) consensus.onAnnounce(msg)
@ -57,27 +71,19 @@ func (consensus *Consensus) handleMessageUpdate(payload []byte) {
} }
// TODO: move to consensus_leader.go later // TODO: move to consensus_leader.go later
func (consensus *Consensus) tryAnnounce(block *types.Block) { func (consensus *Consensus) announce(block *types.Block) {
// here we assume the leader should always be update to date
if block.NumberU64() != consensus.blockNum {
consensus.getLogger().Debug("tryAnnounce blockNum not match", "blockNum", block.NumberU64())
return
}
if !consensus.PubKey.IsEqual(consensus.LeaderPubKey) {
consensus.getLogger().Debug("tryAnnounce key not match", "myKey", consensus.PubKey, "leaderKey", consensus.LeaderPubKey)
return
}
blockHash := block.Hash() blockHash := block.Hash()
copy(consensus.blockHash[:], blockHash[:]) copy(consensus.blockHash[:], blockHash[:])
// prepare message and broadcast to validators // prepare message and broadcast to validators
encodedBlock, err := rlp.EncodeToBytes(block) encodedBlock, err := rlp.EncodeToBytes(block)
if err != nil { if err != nil {
consensus.getLogger().Debug("tryAnnounce Failed encoding block") consensus.getLogger().Debug("[Announce] Failed encoding block")
return return
} }
consensus.block = encodedBlock consensus.block = encodedBlock
msgToSend := consensus.constructAnnounceMessage() msgToSend := consensus.constructAnnounceMessage()
consensus.getLogger().Debug("[Announce] Switching phase", "From", consensus.phase, "To", Prepare)
consensus.switchPhase(Prepare, true) consensus.switchPhase(Prepare, true)
// save announce message to pbftLog // save announce message to pbftLog
@ -86,7 +92,7 @@ func (consensus *Consensus) tryAnnounce(block *types.Block) {
_ = protobuf.Unmarshal(msgPayload, msg) _ = protobuf.Unmarshal(msgPayload, msg)
pbftMsg, err := ParsePbftMessage(msg) pbftMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("tryAnnounce unable to parse pbft message", "error", err) consensus.getLogger().Warn("[Announce] Unable to parse pbft message", "error", err)
return return
} }
@ -98,35 +104,35 @@ func (consensus *Consensus) tryAnnounce(block *types.Block) {
// Construct broadcast p2p message // Construct broadcast p2p message
if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil { if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil {
consensus.getLogger().Warn("cannot send announce message", "groupID", p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))) consensus.getLogger().Warn("[Announce] Cannot send announce message", "groupID", p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID)))
} else { } else {
consensus.getLogger().Debug("sent announce message") consensus.getLogger().Debug("[Announce] Sent Announce Message!!", "BlockHash", block.Hash(), "BlockNum", block.NumberU64())
} }
} }
func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
consensus.getLogger().Debug("receive announce message") consensus.getLogger().Debug("[OnAnnounce] Receive announce message")
if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal { if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal {
return return
} }
senderKey, err := consensus.verifySenderKey(msg) senderKey, err := consensus.verifySenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onAnnounce verifySenderKey failed", "error", err) consensus.getLogger().Debug("[OnAnnounce] VerifySenderKey failed", "error", err)
return return
} }
if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck { if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck {
consensus.getLogger().Warn("onAnnounce senderKey not match leader PubKey", "senderKey", senderKey.SerializeToHexStr(), "leaderKey", consensus.LeaderPubKey.SerializeToHexStr()) consensus.getLogger().Warn("[OnAnnounce] SenderKey not match leader PubKey", "senderKey", senderKey.SerializeToHexStr(), "leaderKey", consensus.LeaderPubKey.SerializeToHexStr())
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Debug("onAnnounce Failed to verify leader signature", "error", err) consensus.getLogger().Debug("[OnAnnounce] Failed to verify leader signature", "error", err)
return return
} }
recvMsg, err := ParsePbftMessage(msg) recvMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onAnnounce Unparseable leader message", "error", err) consensus.getLogger().Debug("[OnAnnounce] Unparseable leader message", "error", err, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
block := recvMsg.Payload block := recvMsg.Payload
@ -135,39 +141,28 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
var blockObj types.Block var blockObj types.Block
err = rlp.DecodeBytes(block, &blockObj) err = rlp.DecodeBytes(block, &blockObj)
if err != nil { if err != nil {
consensus.getLogger().Warn("onAnnounce Unparseable block header data", "error", err) consensus.getLogger().Warn("[OnAnnounce] Unparseable block header data", "error", err, "MsgBlockNum", recvMsg.BlockNum, "MsgPayloadBlockNum", blockObj.NumberU64())
return return
} }
if blockObj.NumberU64() != recvMsg.BlockNum || recvMsg.BlockNum < consensus.blockNum { if blockObj.NumberU64() != recvMsg.BlockNum || recvMsg.BlockNum < consensus.blockNum {
consensus.getLogger().Warn("blockNum not match", "msgBlock", recvMsg.BlockNum, "blockNum", blockObj.NumberU64()) consensus.getLogger().Warn("[OnAnnounce] BlockNum not match", "MsgBlockNum", recvMsg.BlockNum, "blockNum", blockObj.NumberU64())
return return
} }
if consensus.mode.Mode() == Normal { if consensus.mode.Mode() == Normal {
// skip verify header when node is in Syncing mode // skip verify header when node is in Syncing mode
if err := consensus.VerifyHeader(consensus.ChainReader, blockObj.Header(), false); err != nil { if err := consensus.VerifyHeader(consensus.ChainReader, blockObj.Header(), false); err != nil {
consensus.getLogger().Warn("onAnnounce block content is not verified successfully", "error", err, "inChain", consensus.ChainReader.CurrentHeader().Number, "got", blockObj.Header().Number) consensus.getLogger().Warn("[OnAnnounce] Block content is not verified successfully", "error", err, "inChain", consensus.ChainReader.CurrentHeader().Number, "MsgBlockNum", blockObj.Header().Number)
return return
} }
} }
// skip verify block in Syncing mode
if consensus.BlockVerifier == nil || consensus.mode.Mode() != Normal {
// do nothing
} else if err := consensus.BlockVerifier(&blockObj); err != nil {
// TODO ek – maybe we could do this in commit phase
err := ctxerror.New("block verification failed",
"blockHash", blockObj.Hash(),
).WithCause(err)
ctxerror.Log15(utils.GetLogger().Warn, err)
return
}
//blockObj.Logger(consensus.getLogger()).Debug("received announce", "viewID", recvMsg.ViewID, "msgBlockNum", recvMsg.BlockNum) //blockObj.Logger(consensus.getLogger()).Debug("received announce", "viewID", recvMsg.ViewID, "msgBlockNum", recvMsg.BlockNum)
logMsgs := consensus.pbftLog.GetMessagesByTypeSeqView(msg_pb.MessageType_ANNOUNCE, recvMsg.BlockNum, recvMsg.ViewID) logMsgs := consensus.pbftLog.GetMessagesByTypeSeqView(msg_pb.MessageType_ANNOUNCE, recvMsg.BlockNum, recvMsg.ViewID)
if len(logMsgs) > 0 { if len(logMsgs) > 0 {
if logMsgs[0].BlockHash != blockObj.Header().Hash() { if logMsgs[0].BlockHash != blockObj.Header().Hash() {
consensus.getLogger().Debug("onAnnounce leader is malicious", "leaderKey", consensus.LeaderPubKey) consensus.getLogger().Debug("[OnAnnounce] Leader is malicious", "leaderKey", consensus.LeaderPubKey.SerializeToHexStr())
consensus.startViewChange(consensus.viewID + 1) consensus.startViewChange(consensus.viewID + 1)
} }
return return
@ -176,7 +171,7 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
copy(blockPayload[:], block[:]) copy(blockPayload[:], block[:])
consensus.block = blockPayload consensus.block = blockPayload
consensus.blockHash = recvMsg.BlockHash consensus.blockHash = recvMsg.BlockHash
consensus.getLogger().Debug("announce block added", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnAnnounce] Announce Block Added", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
consensus.pbftLog.AddMessage(recvMsg) consensus.pbftLog.AddMessage(recvMsg)
consensus.pbftLog.AddBlock(&blockObj) consensus.pbftLog.AddBlock(&blockObj)
@ -191,37 +186,31 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
defer consensus.mutex.Unlock() defer consensus.mutex.Unlock()
if consensus.checkViewID(recvMsg) != nil { if consensus.checkViewID(recvMsg) != nil {
consensus.getLogger().Debug("viewID check failed", "msgViewID", recvMsg.ViewID, "msgBlockNum", recvMsg.BlockNum) consensus.getLogger().Debug("[OnAnnounce] ViewID check failed", "MsgViewID", recvMsg.ViewID, "msgBlockNum", recvMsg.BlockNum)
return return
} }
consensus.tryPrepare(blockObj.Header().Hash()) consensus.prepare(&blockObj)
return return
} }
// tryPrepare will try to send prepare message // tryPrepare will try to send prepare message
func (consensus *Consensus) tryPrepare(blockHash common.Hash) { func (consensus *Consensus) prepare(block *types.Block) {
var hash common.Hash // if consensus.blockNum != block.NumberU64() || !consensus.pbftLog.HasMatchingViewAnnounce(consensus.blockNum, consensus.viewID, hash) {
copy(hash[:], blockHash[:]) // consensus.getLogger().Debug("blockNum or announce message not match")
block := consensus.pbftLog.GetBlockByHash(hash) // return
if block == nil { // }
return
}
if consensus.blockNum != block.NumberU64() || !consensus.pbftLog.HasMatchingViewAnnounce(consensus.blockNum, consensus.viewID, hash) {
consensus.getLogger().Debug("blockNum or announce message not match")
return
}
consensus.getLogger().Debug("[Announce] Switching Phase", "From", consensus.phase, "To", Prepare)
consensus.switchPhase(Prepare, true) consensus.switchPhase(Prepare, true)
// Construct and send prepare message // Construct and send prepare message
msgToSend := consensus.constructPrepareMessage() msgToSend := consensus.constructPrepareMessage()
// TODO: this will not return immediatey, may block // TODO: this will not return immediatey, may block
if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil { if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil {
consensus.getLogger().Warn("cannot send prepare message") consensus.getLogger().Warn("[OnAnnounce] Cannot send prepare message")
} else { } else {
consensus.getLogger().Info("sent prepare message") consensus.getLogger().Info("[OnAnnounce] Sent Prepare Message!!", "BlockHash", block.Hash(), "BlockNum", block.NumberU64())
} }
} }
@ -233,28 +222,28 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
senderKey, err := consensus.verifySenderKey(msg) senderKey, err := consensus.verifySenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onPrepare verifySenderKey failed", "error", err) consensus.getLogger().Debug("[OnPrepare] VerifySenderKey failed", "error", err)
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Debug("onPrepare Failed to verify sender's signature", "error", err) consensus.getLogger().Debug("[OnPrepare] Failed to verify sender's signature", "error", err)
return return
} }
recvMsg, err := ParsePbftMessage(msg) recvMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("[Consensus] onPrepare Unparseable validator message", "error", err) consensus.getLogger().Debug("[OnPrepare] Unparseable validator message", "error", err)
return return
} }
if recvMsg.ViewID != consensus.viewID || recvMsg.BlockNum != consensus.blockNum { if recvMsg.ViewID != consensus.viewID || recvMsg.BlockNum != consensus.blockNum {
consensus.getLogger().Debug("onPrepare message not match", consensus.getLogger().Debug("[OnPrepare] Message ViewId or BlockNum not match",
"msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
if !consensus.pbftLog.HasMatchingViewAnnounce(consensus.blockNum, consensus.viewID, recvMsg.BlockHash) { if !consensus.pbftLog.HasMatchingViewAnnounce(consensus.blockNum, consensus.viewID, recvMsg.BlockHash) {
consensus.getLogger().Debug("onPrepare no matching announce message", "blockHash", recvMsg.BlockHash) consensus.getLogger().Debug("[OnPrepare] No Matching Announce message", "MsgblockHash", recvMsg.BlockHash, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
@ -268,13 +257,13 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
defer consensus.mutex.Unlock() defer consensus.mutex.Unlock()
if len(prepareSigs) >= consensus.Quorum() { if len(prepareSigs) >= consensus.Quorum() {
// already have enough signatures // already have enough signatures
consensus.getLogger().Info("[OnPrepare] Received Additional Prepare Message", "ValidatorPubKey", validatorPubKey)
return return
} }
// proceed only when the message is not received before // proceed only when the message is not received before
_, ok := prepareSigs[validatorPubKey] _, ok := prepareSigs[validatorPubKey]
if ok { if ok {
consensus.getLogger().Debug("Already received prepare message from the validator", "validatorPubKey", validatorPubKey) consensus.getLogger().Debug("[OnPrepare] Already Received prepare message from the validator", "ValidatorPubKey", validatorPubKey)
return return
} }
@ -282,23 +271,23 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
var sign bls.Sign var sign bls.Sign
err = sign.Deserialize(prepareSig) err = sign.Deserialize(prepareSig)
if err != nil { if err != nil {
consensus.getLogger().Error("Failed to deserialize bls signature", "validatorPubKey", validatorPubKey) consensus.getLogger().Error("[OnPrepare] Failed to deserialize bls signature", "ValidatorPubKey", validatorPubKey)
return return
} }
if !sign.VerifyHash(recvMsg.SenderPubkey, consensus.blockHash[:]) { if !sign.VerifyHash(recvMsg.SenderPubkey, consensus.blockHash[:]) {
consensus.getLogger().Error("Received invalid BLS signature", "validatorPubKey", validatorPubKey) consensus.getLogger().Error("[OnPrepare] Received invalid BLS signature", "ValidatorPubKey", validatorPubKey)
return return
} }
consensus.getLogger().Debug("Received new prepare signature", "numReceivedSoFar", len(prepareSigs), "validatorPubKey", validatorPubKey, "PublicKeys", len(consensus.PublicKeys)) consensus.getLogger().Debug("[OnPrepare] Received New Prepare Signature", "NumReceivedSoFar", len(prepareSigs), "validatorPubKey", validatorPubKey, "PublicKeys", len(consensus.PublicKeys))
prepareSigs[validatorPubKey] = &sign prepareSigs[validatorPubKey] = &sign
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
if err := prepareBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil { if err := prepareBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil {
ctxerror.Warn(consensus.getLogger(), err, "prepareBitmap.SetKey failed") ctxerror.Warn(consensus.getLogger(), err, "[OnPrepare] prepareBitmap.SetKey failed")
} }
if len(prepareSigs) >= consensus.Quorum() { if len(prepareSigs) >= consensus.Quorum() {
consensus.switchPhase(Commit, true) consensus.getLogger().Debug("[OnPrepare] Received Enough Prepare Signatures", "NumReceivedSoFar", len(prepareSigs), "PublicKeys", len(consensus.PublicKeys))
// Construct and broadcast prepared message // Construct and broadcast prepared message
msgToSend, aggSig := consensus.constructPreparedMessage() msgToSend, aggSig := consensus.constructPreparedMessage()
consensus.aggregatedPrepareSig = aggSig consensus.aggregatedPrepareSig = aggSig
@ -309,63 +298,68 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
_ = protobuf.Unmarshal(msgPayload, msg) _ = protobuf.Unmarshal(msgPayload, msg)
pbftMsg, err := ParsePbftMessage(msg) pbftMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onPrepare unable to parse pbft message", "error", err) consensus.getLogger().Warn("[OnPrepare] Unable to parse pbft message", "error", err)
return return
} }
consensus.pbftLog.AddMessage(pbftMsg) consensus.pbftLog.AddMessage(pbftMsg)
if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil { if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil {
consensus.getLogger().Warn("cannot send prepared message") consensus.getLogger().Warn("[OnPrepare] Cannot send prepared message")
} else { } else {
consensus.getLogger().Debug("sent prepared message") consensus.getLogger().Debug("[OnPrepare] Sent Prepared Message!!", "BlockHash", consensus.blockHash, "BlockNum", consensus.blockNum)
} }
consensus.getLogger().Debug("[OnPrepare] Switching phase", "From", consensus.phase, "To", Commit)
consensus.switchPhase(Commit, true)
// Leader add commit phase signature // Leader add commit phase signature
blockNumHash := make([]byte, 8) blockNumHash := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, consensus.blockNum) binary.LittleEndian.PutUint64(blockNumHash, consensus.blockNum)
commitPayload := append(blockNumHash, consensus.blockHash[:]...) commitPayload := append(blockNumHash, consensus.blockHash[:]...)
consensus.commitSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(commitPayload) consensus.commitSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(commitPayload)
if err := consensus.commitBitmap.SetKey(consensus.PubKey, true); err != nil {
consensus.getLogger().Debug("[OnPrepare] Leader commit bitmap set failed")
}
} }
return return
} }
func (consensus *Consensus) onPrepared(msg *msg_pb.Message) { func (consensus *Consensus) onPrepared(msg *msg_pb.Message) {
consensus.getLogger().Debug("receive prepared message") consensus.getLogger().Debug("[OnPrepared] Received Prepared message")
if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal { if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal {
return return
} }
senderKey, err := consensus.verifySenderKey(msg) senderKey, err := consensus.verifySenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onPrepared verifySenderKey failed", "error", err) consensus.getLogger().Debug("[OnPrepared] VerifySenderKey failed", "error", err)
return return
} }
if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck { if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck {
consensus.getLogger().Warn("onPrepared senderKey not match leader PubKey") consensus.getLogger().Warn("[OnPrepared] SenderKey not match leader PubKey")
return return
} }
if err := verifyMessageSig(senderKey, msg); err != nil { if err := verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Debug("onPrepared Failed to verify sender's signature", "error", err) consensus.getLogger().Debug("[OnPrepared] Failed to verify sender's signature", "error", err)
return return
} }
recvMsg, err := ParsePbftMessage(msg) recvMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onPrepared unparseable validator message", "error", err) consensus.getLogger().Debug("[OnPrepared] Unparseable validator message", "error", err)
return return
} }
consensus.getLogger().Info("onPrepared received prepared message", "msgBlock", recvMsg.BlockNum, "msgViewID", recvMsg.ViewID) consensus.getLogger().Info("[OnPrepared] Received prepared message", "MsgBlockNum", recvMsg.BlockNum, "MsgViewID", recvMsg.ViewID)
if recvMsg.BlockNum < consensus.blockNum { if recvMsg.BlockNum < consensus.blockNum {
consensus.getLogger().Debug("old block received, ignoring", consensus.getLogger().Debug("Old Block Received, ignoring!!",
"msgBlock", recvMsg.BlockNum) "MsgBlockNum", recvMsg.BlockNum)
return return
} }
blockHash := recvMsg.BlockHash blockHash := recvMsg.BlockHash
aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 0) aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 0)
if err != nil { if err != nil {
consensus.getLogger().Error("readSignatureBitmapPayload failed", "error", err) consensus.getLogger().Error("ReadSignatureBitmapPayload failed!!", "error", err)
return return
} }
@ -374,34 +368,34 @@ func (consensus *Consensus) onPrepared(msg *msg_pb.Message) {
// check has 2f+1 signatures // check has 2f+1 signatures
if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() { if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() {
consensus.getLogger().Debug("not have enough signature", "need", consensus.Quorum(), "have", count) consensus.getLogger().Debug("Not enough signatures in the Prepared msg", "Need", consensus.Quorum(), "Got", count)
return return
} }
if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) { if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) {
myBlockHash := common.Hash{} myBlockHash := common.Hash{}
myBlockHash.SetBytes(consensus.blockHash[:]) myBlockHash.SetBytes(consensus.blockHash[:])
consensus.getLogger().Warn("onPrepared failed to verify multi signature for prepare phase", "blockHash", blockHash, "myBlockHash", myBlockHash) consensus.getLogger().Warn("[OnPrepared] failed to verify multi signature for prepare phase", "MsgBlockHash", recvMsg.BlockHash, "myBlockHash", myBlockHash)
return return
} }
consensus.getLogger().Debug("prepared message added", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnPrepared] Prepared message added", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
consensus.pbftLog.AddMessage(recvMsg) consensus.pbftLog.AddMessage(recvMsg)
if consensus.mode.Mode() == ViewChanging { if consensus.mode.Mode() == ViewChanging {
consensus.getLogger().Debug("viewchanging mode just exist after viewchanging") consensus.getLogger().Debug("[OnPrepared] Exiting after viewchange!!")
return return
} }
consensus.tryCatchup() consensus.tryCatchup()
if consensus.checkViewID(recvMsg) != nil { if consensus.checkViewID(recvMsg) != nil {
consensus.getLogger().Debug("viewID check failed", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnPrepared] ViewID check failed", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
if recvMsg.BlockNum > consensus.blockNum { if recvMsg.BlockNum > consensus.blockNum {
consensus.getLogger().Debug("future block received, ignoring", consensus.getLogger().Debug("[OnPrepared] Future Block Received, ignoring!!",
"msgBlock", recvMsg.BlockNum) "MsgBlockNum", recvMsg.BlockNum)
return return
} }
@ -409,9 +403,9 @@ func (consensus *Consensus) onPrepared(msg *msg_pb.Message) {
consensus.prepareBitmap = mask consensus.prepareBitmap = mask
// Construct and send the commit message // Construct and send the commit message
blockNumHash := make([]byte, 8) blockNumBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, consensus.blockNum) binary.LittleEndian.PutUint64(blockNumBytes, consensus.blockNum)
commitPayload := append(blockNumHash, consensus.blockHash[:]...) commitPayload := append(blockNumBytes, consensus.blockHash[:]...)
msgToSend := consensus.constructCommitMessage(commitPayload) msgToSend := consensus.constructCommitMessage(commitPayload)
// TODO: genesis account node delay for 1 second, this is a temp fix for allows FN nodes to earning reward // TODO: genesis account node delay for 1 second, this is a temp fix for allows FN nodes to earning reward
@ -420,11 +414,12 @@ func (consensus *Consensus) onPrepared(msg *msg_pb.Message) {
} }
if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil { if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil {
consensus.getLogger().Warn("cannot send commit message") consensus.getLogger().Warn("[OnPrepared] Cannot send commit message!!")
} else { } else {
consensus.getLogger().Debug("sent commit message") consensus.getLogger().Debug("[OnPrepared] Sent Commit Message!!", "BlockHash", consensus.blockHash, "BlockNum", consensus.blockNum)
} }
consensus.getLogger().Debug("[OnPrepared] Switching phase", "From", consensus.phase, "To", Commit)
consensus.switchPhase(Commit, true) consensus.switchPhase(Commit, true)
return return
@ -438,32 +433,32 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
senderKey, err := consensus.verifySenderKey(msg) senderKey, err := consensus.verifySenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onCommit verifySenderKey failed", "error", err) consensus.getLogger().Debug("[OnCommit] VerifySenderKey Failed", "error", err)
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Debug("onCommit Failed to verify sender's signature", "error", err) consensus.getLogger().Debug("[OnCommit] Failed to verify sender's signature", "error", err)
return return
} }
recvMsg, err := ParsePbftMessage(msg) recvMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Debug("onCommit parse pbft message failed", "error", err) consensus.getLogger().Debug("[OnCommit] Parse pbft message failed", "error", err)
return return
} }
if recvMsg.ViewID != consensus.viewID || recvMsg.BlockNum != consensus.blockNum { if recvMsg.ViewID != consensus.viewID || recvMsg.BlockNum != consensus.blockNum {
consensus.getLogger().Debug("blockNum/viewID not match", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnCommit] BlockNum/viewID not match", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum, "ValidatorPubKey", recvMsg.SenderPubkey.SerializeToHexStr())
return return
} }
if !consensus.pbftLog.HasMatchingAnnounce(consensus.blockNum, recvMsg.BlockHash) { if !consensus.pbftLog.HasMatchingAnnounce(consensus.blockNum, recvMsg.BlockHash) {
consensus.getLogger().Debug("cannot find matching blockhash") consensus.getLogger().Debug("[OnCommit] Cannot find matching blockhash", "MsgBlockHash", recvMsg.BlockHash, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
if !consensus.pbftLog.HasMatchingPrepared(consensus.blockNum, recvMsg.BlockHash) { if !consensus.pbftLog.HasMatchingPrepared(consensus.blockNum, recvMsg.BlockHash) {
consensus.getLogger().Debug("cannot find matching prepared message", "blockHash", recvMsg.BlockHash) consensus.getLogger().Debug("[OnCommit] Cannot find matching prepared message", "blockHash", recvMsg.BlockHash)
return return
} }
@ -475,7 +470,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
defer consensus.mutex.Unlock() defer consensus.mutex.Unlock()
if !consensus.IsValidatorInCommittee(recvMsg.SenderPubkey) { if !consensus.IsValidatorInCommittee(recvMsg.SenderPubkey) {
consensus.getLogger().Error("Invalid validator", "validatorPubKey", validatorPubKey) consensus.getLogger().Error("[OnCommit] Invalid validator", "validatorPubKey", validatorPubKey)
return return
} }
@ -485,61 +480,73 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
// proceed only when the message is not received before // proceed only when the message is not received before
_, ok := commitSigs[validatorPubKey] _, ok := commitSigs[validatorPubKey]
if ok { if ok {
consensus.getLogger().Debug("Already received commit message from the validator", "validatorPubKey", validatorPubKey) consensus.getLogger().Info("[OnCommit] Already received commit message from the validator", "validatorPubKey", validatorPubKey)
return return
} }
// already had enough signautres quorumWasMet := len(commitSigs) >= consensus.Quorum()
if len(commitSigs) >= consensus.Quorum() {
return
}
// Verify the signature on commitPayload is correct // Verify the signature on commitPayload is correct
var sign bls.Sign var sign bls.Sign
err = sign.Deserialize(commitSig) err = sign.Deserialize(commitSig)
if err != nil { if err != nil {
consensus.getLogger().Debug("Failed to deserialize bls signature", "validatorPubKey", validatorPubKey) consensus.getLogger().Debug("[OnCommit] Failed to deserialize bls signature", "validatorPubKey", validatorPubKey)
return return
} }
blockNumHash := make([]byte, 8) blockNumHash := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, recvMsg.BlockNum) binary.LittleEndian.PutUint64(blockNumHash, recvMsg.BlockNum)
commitPayload := append(blockNumHash, recvMsg.BlockHash[:]...) commitPayload := append(blockNumHash, recvMsg.BlockHash[:]...)
if !sign.VerifyHash(recvMsg.SenderPubkey, commitPayload) { if !sign.VerifyHash(recvMsg.SenderPubkey, commitPayload) {
consensus.getLogger().Error("cannot verify commit message", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Error("[OnCommit] Cannot verify commit message", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
return return
} }
consensus.getLogger().Debug("Received new commit message", "numReceivedSoFar", len(commitSigs), "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum, "validatorPubKey", validatorPubKey) consensus.getLogger().Debug("[OnCommit] Received new commit message", "numReceivedSoFar", len(commitSigs), "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum, "validatorPubKey", validatorPubKey)
commitSigs[validatorPubKey] = &sign commitSigs[validatorPubKey] = &sign
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
if err := commitBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil { if err := commitBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil {
ctxerror.Warn(consensus.getLogger(), err, "commitBitmap.SetKey failed") ctxerror.Warn(consensus.getLogger(), err, "[OnCommit] commitBitmap.SetKey failed")
} }
if len(commitSigs) >= consensus.Quorum() { quorumIsMet := len(commitSigs) >= consensus.Quorum()
consensus.getLogger().Info("Enough commits received!", "num", len(commitSigs)) rewardThresholdIsMet := len(commitSigs) >= consensus.RewardThreshold()
consensus.finalizeCommits()
if !quorumWasMet && quorumIsMet {
consensus.getLogger().Info("[OnCommit] 2/3 Enough commits received", "NumCommits", len(commitSigs))
go func(viewID uint32) {
time.Sleep(2 * time.Second)
consensus.getLogger().Debug("[OnCommit] Commit Grace Period Ended", "NumCommits", len(commitSigs))
consensus.commitFinishChan <- viewID
}(consensus.viewID)
}
if rewardThresholdIsMet {
go func(viewID uint32) {
consensus.commitFinishChan <- viewID
consensus.getLogger().Debug("[OnCommit] 90% Enough commits received", "NumCommits", len(commitSigs))
}(consensus.viewID)
} }
} }
func (consensus *Consensus) finalizeCommits() { func (consensus *Consensus) finalizeCommits() {
consensus.getLogger().Info("finalizing block", "num", len(consensus.commitSigs)) consensus.getLogger().Info("[Finalizing] Finalizing Block", "NumCommits", len(consensus.commitSigs))
consensus.switchPhase(Announce, true)
// Construct and broadcast committed message // Construct and broadcast committed message
msgToSend, aggSig := consensus.constructCommittedMessage() msgToSend, aggSig := consensus.constructCommittedMessage()
consensus.aggregatedCommitSig = aggSig consensus.aggregatedCommitSig = aggSig
if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil { if err := consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)); err != nil {
ctxerror.Warn(consensus.getLogger(), err, "cannot send committed message") ctxerror.Warn(consensus.getLogger(), err, "[Finalizing] Cannot send committed message")
} else { } else {
consensus.getLogger().Debug("sent committed message", "len", len(msgToSend)) consensus.getLogger().Debug("[Finalizing] Sent Committed Message", "BlockHash", consensus.blockHash, "BlockNum", consensus.blockNum)
} }
consensus.getLogger().Debug("[Finalizing] Switching phase", "From", consensus.phase, "To", Announce)
consensus.switchPhase(Announce, true)
var blockObj types.Block var blockObj types.Block
err := rlp.DecodeBytes(consensus.block, &blockObj) err := rlp.DecodeBytes(consensus.block, &blockObj)
if err != nil { if err != nil {
consensus.getLogger().Debug("failed to construct the new block after consensus") consensus.getLogger().Debug("[Finalizing] failed to construct the new block after consensus")
} }
// Sign the block // Sign the block
@ -568,21 +575,24 @@ func (consensus *Consensus) finalizeCommits() {
if consensus.consensusTimeout[timeoutBootstrap].IsActive() { if consensus.consensusTimeout[timeoutBootstrap].IsActive() {
consensus.consensusTimeout[timeoutBootstrap].Stop() consensus.consensusTimeout[timeoutBootstrap].Stop()
consensus.getLogger().Debug("start consensus timer; stop bootstrap timer only once") consensus.getLogger().Debug("[Finalizing] Start consensus timer; stop bootstrap timer only once")
} else { } else {
consensus.getLogger().Debug("start consensus timer") consensus.getLogger().Debug("[Finalizing] Start consensus timer")
} }
consensus.consensusTimeout[timeoutConsensus].Start() consensus.consensusTimeout[timeoutConsensus].Start()
consensus.OnConsensusDone(&blockObj) consensus.OnConsensusDone(&blockObj)
consensus.getLogger().Info("HOORAY!!!!!!! CONSENSUS REACHED!!!!!!!", "numOfSignatures", len(consensus.commitSigs)) consensus.getLogger().Info("HOORAY!!!!!!! CONSENSUS REACHED!!!!!!!", "numOfSignatures", len(consensus.commitSigs), "BlockNum", consensus.blockNum-1, "ViewId", consensus.viewID-1, "BlockHash", blockObj.Hash())
// TODO: wait for validators receive committed message; remove this temporary delay
time.Sleep(time.Second)
// Send signal to Node so the new block can be added and new round of consensus can be triggered // Send signal to Node so the new block can be added and new round of consensus can be triggered
consensus.ReadySignal <- struct{}{} consensus.ReadySignal <- struct{}{}
} }
func (consensus *Consensus) onCommitted(msg *msg_pb.Message) { func (consensus *Consensus) onCommitted(msg *msg_pb.Message) {
consensus.getLogger().Debug("receive committed message") consensus.getLogger().Debug("[OnCommitted] Receive committed message")
if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal { if consensus.PubKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal {
return return
@ -590,53 +600,58 @@ func (consensus *Consensus) onCommitted(msg *msg_pb.Message) {
senderKey, err := consensus.verifySenderKey(msg) senderKey, err := consensus.verifySenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onCommitted verifySenderKey failed", "error", err) consensus.getLogger().Warn("[OnCommitted] verifySenderKey failed", "error", err)
return return
} }
if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck { if !senderKey.IsEqual(consensus.LeaderPubKey) && consensus.mode.Mode() == Normal && !consensus.ignoreViewIDCheck {
consensus.getLogger().Warn("onCommitted senderKey not match leader PubKey") consensus.getLogger().Warn("[OnCommitted] senderKey not match leader PubKey")
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Warn("onCommitted Failed to verify sender's signature", "error", err) consensus.getLogger().Warn("[OnCommitted] Failed to verify sender's signature", "error", err)
return return
} }
recvMsg, err := ParsePbftMessage(msg) recvMsg, err := ParsePbftMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onCommitted unable to parse msg", "error", err) consensus.getLogger().Warn("[OnCommitted] unable to parse msg", "error", err)
return return
} }
if recvMsg.BlockNum < consensus.blockNum { if recvMsg.BlockNum < consensus.blockNum {
consensus.getLogger().Info("[OnCommitted] Received Old Blocks!!", "MsgBlockNum", recvMsg.BlockNum)
return return
} }
aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 0) aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 0)
if err != nil { if err != nil {
consensus.getLogger().Error("readSignatureBitmapPayload failed", "error", err) consensus.getLogger().Error("[OnCommitted] readSignatureBitmapPayload failed", "error", err)
return return
} }
// check has 2f+1 signatures // check has 2f+1 signatures
if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() { if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() {
consensus.getLogger().Debug("not have enough signature", "need", consensus.Quorum(), "have", count) consensus.getLogger().Warn("[OnCommitted] Not enough signature in committed msg", "need", consensus.Quorum(), "got", count)
return return
} }
blockNumHash := make([]byte, 8) blockNumBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, recvMsg.BlockNum) binary.LittleEndian.PutUint64(blockNumBytes, recvMsg.BlockNum)
commitPayload := append(blockNumHash, recvMsg.BlockHash[:]...) commitPayload := append(blockNumBytes, recvMsg.BlockHash[:]...)
if !aggSig.VerifyHash(mask.AggregatePublic, commitPayload) { if !aggSig.VerifyHash(mask.AggregatePublic, commitPayload) {
consensus.getLogger().Error("Failed to verify the multi signature for commit phase", "msgBlock", recvMsg.BlockNum) consensus.getLogger().Error("[OnCommitted] Failed to verify the multi signature for commit phase", "MsgBlockNum", recvMsg.BlockNum)
return return
} }
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
consensus.aggregatedCommitSig = aggSig consensus.aggregatedCommitSig = aggSig
consensus.commitBitmap = mask consensus.commitBitmap = mask
consensus.getLogger().Debug("committed message added", "msgViewID", recvMsg.ViewID, "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnCommitted] Committed message added", "MsgViewID", recvMsg.ViewID, "MsgBlockNum", recvMsg.BlockNum)
consensus.pbftLog.AddMessage(recvMsg) consensus.pbftLog.AddMessage(recvMsg)
if recvMsg.BlockNum-consensus.blockNum > consensusBlockNumBuffer { if recvMsg.BlockNum-consensus.blockNum > consensusBlockNumBuffer {
consensus.getLogger().Debug("onCommitted out of sync", "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[OnCommitted] out of sync", "MsgBlockNum", recvMsg.BlockNum)
go func() { go func() {
select { select {
case consensus.blockNumLowChan <- struct{}{}: case consensus.blockNumLowChan <- struct{}{}:
@ -656,14 +671,12 @@ func (consensus *Consensus) onCommitted(msg *msg_pb.Message) {
// } // }
consensus.tryCatchup() consensus.tryCatchup()
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
if consensus.consensusTimeout[timeoutBootstrap].IsActive() { if consensus.consensusTimeout[timeoutBootstrap].IsActive() {
consensus.consensusTimeout[timeoutBootstrap].Stop() consensus.consensusTimeout[timeoutBootstrap].Stop()
consensus.getLogger().Debug("start consensus timer; stop bootstrap timer only once") consensus.getLogger().Debug("[OnCommitted] Start consensus timer; stop bootstrap timer only once")
} else { } else {
consensus.getLogger().Debug("start consensus timer") consensus.getLogger().Debug("[OnCommitted] Start consensus timer")
} }
consensus.consensusTimeout[timeoutConsensus].Start() consensus.consensusTimeout[timeoutConsensus].Start()
return return
@ -671,7 +684,7 @@ func (consensus *Consensus) onCommitted(msg *msg_pb.Message) {
// try to catch up if fall behind // try to catch up if fall behind
func (consensus *Consensus) tryCatchup() { func (consensus *Consensus) tryCatchup() {
consensus.getLogger().Info("tryCatchup: commit new blocks") consensus.getLogger().Info("[TryCatchup] commit new blocks")
// if consensus.phase != Commit && consensus.mode.Mode() == Normal { // if consensus.phase != Commit && consensus.mode.Mode() == Normal {
// return // return
// } // }
@ -682,27 +695,34 @@ func (consensus *Consensus) tryCatchup() {
break break
} }
if len(msgs) > 1 { if len(msgs) > 1 {
consensus.getLogger().Error("[PBFT] DANGER!!! we should only get one committed message for a given blockNum", "numMsgs", len(msgs)) consensus.getLogger().Error("[TryCatchup] DANGER!!! we should only get one committed message for a given blockNum", "numMsgs", len(msgs))
} }
consensus.getLogger().Info("committed message found") consensus.getLogger().Info("[TryCatchup] committed message found")
block := consensus.pbftLog.GetBlockByHash(msgs[0].BlockHash) block := consensus.pbftLog.GetBlockByHash(msgs[0].BlockHash)
if block == nil { if block == nil {
break break
} }
if consensus.BlockVerifier == nil {
// do nothing
} else if err := consensus.BlockVerifier(block); err != nil {
consensus.getLogger().Info("[TryCatchup]block verification faied")
return
}
if block.ParentHash() != consensus.ChainReader.CurrentHeader().Hash() { if block.ParentHash() != consensus.ChainReader.CurrentHeader().Hash() {
consensus.getLogger().Debug("[PBFT] parent block hash not match") consensus.getLogger().Debug("[TryCatchup] parent block hash not match")
break break
} }
consensus.getLogger().Info("block found to commit") consensus.getLogger().Info("[TryCatchup] block found to commit")
preparedMsgs := consensus.pbftLog.GetMessagesByTypeSeqHash(msg_pb.MessageType_PREPARED, msgs[0].BlockNum, msgs[0].BlockHash) preparedMsgs := consensus.pbftLog.GetMessagesByTypeSeqHash(msg_pb.MessageType_PREPARED, msgs[0].BlockNum, msgs[0].BlockHash)
msg := consensus.pbftLog.FindMessageByMaxViewID(preparedMsgs) msg := consensus.pbftLog.FindMessageByMaxViewID(preparedMsgs)
if msg == nil { if msg == nil {
break break
} }
consensus.getLogger().Info("prepared message found to commit") consensus.getLogger().Info("[TryCatchup] prepared message found to commit")
consensus.blockHash = [32]byte{} consensus.blockHash = [32]byte{}
consensus.blockNum = consensus.blockNum + 1 consensus.blockNum = consensus.blockNum + 1
@ -731,20 +751,21 @@ func (consensus *Consensus) tryCatchup() {
block.SetPrepareSig(prepareSig, prepareBitmap) block.SetPrepareSig(prepareSig, prepareBitmap)
block.SetCommitSig(aggSig, bitmap) block.SetCommitSig(aggSig, bitmap)
consensus.getLogger().Info("Adding block to chain") consensus.getLogger().Info("[TryCatchup] Adding block to chain")
consensus.OnConsensusDone(block) consensus.OnConsensusDone(block)
consensus.ResetState() consensus.ResetState()
select { select {
case consensus.VerifiedNewBlock <- block: case consensus.VerifiedNewBlock <- block:
default: default:
consensus.getLogger().Info("[SYNC] consensus verified block send to chan failed", "blockHash", block.Hash()) consensus.getLogger().Info("[TryCatchup] consensus verified block send to chan failed", "blockHash", block.Hash())
continue continue
} }
break break
} }
if currentBlockNum < consensus.blockNum { if currentBlockNum < consensus.blockNum {
consensus.getLogger().Info("[TryCatchup] Catched up!", "From", currentBlockNum, "To", consensus.blockNum)
consensus.switchPhase(Announce, true) consensus.switchPhase(Announce, true)
} }
// catup up and skip from view change trap // catup up and skip from view change trap
@ -763,11 +784,11 @@ func (consensus *Consensus) Start(blockChannel chan *types.Block, stopChan chan
<-startChannel <-startChannel
} }
go func() { go func() {
consensus.getLogger().Info("start consensus", "time", time.Now()) consensus.getLogger().Info("[ConsensusMainLoop] Start consensus", "time", time.Now())
defer close(stoppedChan) defer close(stoppedChan)
ticker := time.NewTicker(3 * time.Second) ticker := time.NewTicker(3 * time.Second)
consensus.consensusTimeout[timeoutBootstrap].Start() consensus.consensusTimeout[timeoutBootstrap].Start()
consensus.getLogger().Debug("start bootstrap timeout only once", "viewID", consensus.viewID, "block", consensus.blockNum) consensus.getLogger().Debug("[ConsensusMainLoop] Start bootstrap timeout (only once)", "viewID", consensus.viewID, "block", consensus.blockNum)
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
@ -779,23 +800,28 @@ func (consensus *Consensus) Start(blockChannel chan *types.Block, stopChan chan
continue continue
} }
if k != timeoutViewChange { if k != timeoutViewChange {
consensus.getLogger().Debug("ops consensus timeout") consensus.getLogger().Debug("[ConsensusMainLoop] Ops Consensus Timeout!!!")
consensus.startViewChange(consensus.viewID + 1) consensus.startViewChange(consensus.viewID + 1)
break break
} else { } else {
consensus.getLogger().Debug("ops view change timeout") consensus.getLogger().Debug("[ConsensusMainLoop] Ops View Change Timeout!!!")
viewID := consensus.mode.ViewID() viewID := consensus.mode.ViewID()
consensus.startViewChange(viewID + 1) consensus.startViewChange(viewID + 1)
break break
} }
} }
case <-consensus.syncReadyChan: case <-consensus.syncReadyChan:
consensus.SetBlockNum(consensus.ChainReader.CurrentHeader().Number.Uint64() + 1) consensus.SetBlockNum(consensus.ChainReader.CurrentHeader().Number.Uint64() + 1)
consensus.getLogger().Info("Node is in sync")
consensus.ignoreViewIDCheck = true consensus.ignoreViewIDCheck = true
case <-consensus.syncNotReadyChan:
consensus.SetBlockNum(consensus.ChainReader.CurrentHeader().Number.Uint64() + 1)
consensus.mode.SetMode(Syncing)
consensus.getLogger().Info("Node is out of sync")
case newBlock := <-blockChannel: case newBlock := <-blockChannel:
consensus.getLogger().Info("receive newBlock", "msgBlock", newBlock.NumberU64()) consensus.getLogger().Info("[ConsensusMainLoop] Received Proposed New Block!", "MsgBlockNum", newBlock.NumberU64())
if consensus.ShardID == 0 { if consensus.ShardID == 0 {
// TODO ek/rj - re-enable this after fixing DRand // TODO ek/rj - re-enable this after fixing DRand
//if core.IsEpochBlock(newBlock) { // Only beacon chain do randomness generation //if core.IsEpochBlock(newBlock) { // Only beacon chain do randomness generation
@ -817,20 +843,29 @@ func (consensus *Consensus) Start(blockChannel chan *types.Block, stopChan chan
if err == nil { if err == nil {
// Verify the randomness // Verify the randomness
_ = blockHash _ = blockHash
consensus.getLogger().Info("Adding randomness into new block", "rnd", rnd) consensus.getLogger().Info("[ConsensusMainLoop] Adding randomness into new block", "rnd", rnd)
newBlock.AddVdf([258]byte{}) // TODO(HB): add real vdf newBlock.AddVdf([258]byte{}) // TODO(HB): add real vdf
} else { } else {
consensus.getLogger().Info("Failed to get randomness", "error", err) //consensus.getLogger().Info("Failed to get randomness", "error", err)
} }
} }
startTime = time.Now() startTime = time.Now()
consensus.getLogger().Debug("STARTING CONSENSUS", "numTxs", len(newBlock.Transactions()), "consensus", consensus, "startTime", startTime, "publicKeys", len(consensus.PublicKeys)) consensus.getLogger().Debug("[ConsensusMainLoop] STARTING CONSENSUS", "numTxs", len(newBlock.Transactions()), "consensus", consensus, "startTime", startTime, "publicKeys", len(consensus.PublicKeys))
consensus.tryAnnounce(newBlock) consensus.announce(newBlock)
case msg := <-consensus.MsgChan: case msg := <-consensus.MsgChan:
consensus.handleMessageUpdate(msg) consensus.handleMessageUpdate(msg)
case viewID := <-consensus.commitFinishChan:
func() {
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
if viewID == consensus.viewID {
consensus.finalizeCommits()
}
}()
case <-stopChan: case <-stopChan:
return return
} }

@ -22,6 +22,7 @@ func (consensus *Consensus) constructViewChangeMessage() []byte {
vcMsg := message.GetViewchange() vcMsg := message.GetViewchange()
vcMsg.ViewId = consensus.mode.GetViewID() vcMsg.ViewId = consensus.mode.GetViewID()
vcMsg.BlockNum = consensus.blockNum vcMsg.BlockNum = consensus.blockNum
vcMsg.ShardId = consensus.ShardID
// sender address // sender address
vcMsg.SenderPubkey = consensus.PubKey.Serialize() vcMsg.SenderPubkey = consensus.PubKey.Serialize()
@ -40,6 +41,7 @@ func (consensus *Consensus) constructViewChangeMessage() []byte {
msgToSign = append(preparedMsg.BlockHash[:], preparedMsg.Payload...) msgToSign = append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
vcMsg.Payload = append(msgToSign[:0:0], msgToSign...) vcMsg.Payload = append(msgToSign[:0:0], msgToSign...)
} }
consensus.getLogger().Debug("[constructViewChangeMessage]", "m1Payload", vcMsg.Payload, "pubKey", consensus.PubKey.SerializeToHexStr())
sign := consensus.priKey.SignHash(msgToSign) sign := consensus.priKey.SignHash(msgToSign)
if sign != nil { if sign != nil {
@ -48,9 +50,9 @@ func (consensus *Consensus) constructViewChangeMessage() []byte {
utils.GetLogger().Error("unable to serialize m1/m2 view change message signature") utils.GetLogger().Error("unable to serialize m1/m2 view change message signature")
} }
viewIDHash := make([]byte, 4) viewIDBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(viewIDHash, consensus.mode.ViewID()) binary.LittleEndian.PutUint32(viewIDBytes, consensus.mode.ViewID())
sign1 := consensus.priKey.SignHash(viewIDHash) sign1 := consensus.priKey.SignHash(viewIDBytes)
if sign1 != nil { if sign1 != nil {
vcMsg.ViewidSig = sign1.Serialize() vcMsg.ViewidSig = sign1.Serialize()
} else { } else {
@ -59,7 +61,7 @@ func (consensus *Consensus) constructViewChangeMessage() []byte {
marshaledMessage, err := consensus.signAndMarshalConsensusMessage(message) marshaledMessage, err := consensus.signAndMarshalConsensusMessage(message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("constructViewChangeMessage failed to sign and marshal the viewchange message", "error", err) utils.GetLogInstance().Error("[constructViewChangeMessage] failed to sign and marshal the viewchange message", "error", err)
} }
return proto.ConstructConsensusMessage(marshaledMessage) return proto.ConstructConsensusMessage(marshaledMessage)
} }
@ -75,13 +77,15 @@ func (consensus *Consensus) constructNewViewMessage() []byte {
} }
vcMsg := message.GetViewchange() vcMsg := message.GetViewchange()
vcMsg.ViewId = consensus.mode.GetViewID() vcMsg.ViewId = consensus.mode.ViewID()
vcMsg.BlockNum = consensus.blockNum vcMsg.BlockNum = consensus.blockNum
vcMsg.ShardId = consensus.ShardID
// sender address // sender address
vcMsg.SenderPubkey = consensus.PubKey.Serialize() vcMsg.SenderPubkey = consensus.PubKey.Serialize()
vcMsg.Payload = consensus.m1Payload vcMsg.Payload = consensus.m1Payload
sig2arr := consensus.GetNilSigsArray() sig2arr := consensus.GetNilSigsArray()
consensus.getLogger().Debug("[constructNewViewMessage] M2 (NIL) type signatures", "len", len(sig2arr))
if len(sig2arr) > 0 { if len(sig2arr) > 0 {
m2Sig := bls_cosi.AggregateSig(sig2arr) m2Sig := bls_cosi.AggregateSig(sig2arr)
vcMsg.M2Aggsigs = m2Sig.Serialize() vcMsg.M2Aggsigs = m2Sig.Serialize()
@ -89,6 +93,8 @@ func (consensus *Consensus) constructNewViewMessage() []byte {
} }
sig3arr := consensus.GetViewIDSigsArray() sig3arr := consensus.GetViewIDSigsArray()
consensus.getLogger().Debug("[constructNewViewMessage] M3 (ViewID) type signatures", "len", len(sig3arr))
// even we check here for safty, m3 type signatures must >= 2f+1
if len(sig3arr) > 0 { if len(sig3arr) > 0 {
m3Sig := bls_cosi.AggregateSig(sig3arr) m3Sig := bls_cosi.AggregateSig(sig3arr)
vcMsg.M3Aggsigs = m3Sig.Serialize() vcMsg.M3Aggsigs = m3Sig.Serialize()
@ -97,7 +103,7 @@ func (consensus *Consensus) constructNewViewMessage() []byte {
marshaledMessage, err := consensus.signAndMarshalConsensusMessage(message) marshaledMessage, err := consensus.signAndMarshalConsensusMessage(message)
if err != nil { if err != nil {
utils.GetLogInstance().Error("constructNewViewMessage failed to sign and marshal the new view message", "error", err) utils.GetLogInstance().Error("[constructNewViewMessage] failed to sign and marshal the new view message", "error", err)
} }
return proto.ConstructConsensusMessage(marshaledMessage) return proto.ConstructConsensusMessage(marshaledMessage)
} }

@ -137,6 +137,7 @@ func (consensus *Consensus) getIndexOfPubKey(pubKey *bls.PublicKey) int {
// ResetViewChangeState reset the state for viewchange // ResetViewChangeState reset the state for viewchange
func (consensus *Consensus) ResetViewChangeState() { func (consensus *Consensus) ResetViewChangeState() {
consensus.getLogger().Debug("[ResetViewChangeState] Resetting view change state", "Phase", consensus.phase)
consensus.mode.SetMode(Normal) consensus.mode.SetMode(Normal)
bhpBitmap, _ := bls_cosi.NewMask(consensus.PublicKeys, nil) bhpBitmap, _ := bls_cosi.NewMask(consensus.PublicKeys, nil)
nilBitmap, _ := bls_cosi.NewMask(consensus.PublicKeys, nil) nilBitmap, _ := bls_cosi.NewMask(consensus.PublicKeys, nil)
@ -172,26 +173,20 @@ func (consensus *Consensus) startViewChange(viewID uint32) {
diff := viewID - consensus.viewID diff := viewID - consensus.viewID
duration := time.Duration(int64(diff) * int64(viewChangeDuration)) duration := time.Duration(int64(diff) * int64(viewChangeDuration))
consensus.getLogger().Info("startViewChange", "viewID", viewID, "timeoutDuration", duration, "nextLeader", consensus.LeaderPubKey.SerializeToHexStr()) consensus.getLogger().Info("[startViewChange]", "ViewChangingID", viewID, "timeoutDuration", duration, "NextLeader", consensus.LeaderPubKey.SerializeToHexStr())
msgToSend := consensus.constructViewChangeMessage() msgToSend := consensus.constructViewChangeMessage()
consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)) consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend))
consensus.consensusTimeout[timeoutViewChange].SetDuration(duration) consensus.consensusTimeout[timeoutViewChange].SetDuration(duration)
consensus.consensusTimeout[timeoutViewChange].Start() consensus.consensusTimeout[timeoutViewChange].Start()
consensus.getLogger().Debug("start view change timer", "viewChangingID", consensus.mode.ViewID()) consensus.getLogger().Debug("[startViewChange] start view change timer", "ViewChangingID", consensus.mode.ViewID())
} }
func (consensus *Consensus) onViewChange(msg *msg_pb.Message) { func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
senderKey, err := consensus.verifyViewChangeSenderKey(msg)
if err != nil {
consensus.getLogger().Debug("onViewChange verifySenderKey failed", "error", err)
return
}
recvMsg, err := ParseViewChangeMessage(msg) recvMsg, err := ParseViewChangeMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onViewChange unable to parse viewchange message") consensus.getLogger().Warn("[onViewChange] Unable To Parse Viewchange Message")
return return
} }
newLeaderKey := recvMsg.LeaderPubkey newLeaderKey := recvMsg.LeaderPubkey
@ -199,20 +194,33 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
return return
} }
if len(consensus.viewIDSigs) >= consensus.Quorum() {
consensus.getLogger().Debug("[onViewChange] Received Enough View Change Messages", "have", len(consensus.viewIDSigs), "need", consensus.Quorum(), "validatorPubKey", recvMsg.SenderPubkey.SerializeToHexStr())
return
}
senderKey, err := consensus.verifyViewChangeSenderKey(msg)
if err != nil {
consensus.getLogger().Debug("[onViewChange] VerifySenderKey Failed", "error", err)
return
}
if consensus.blockNum > recvMsg.BlockNum { if consensus.blockNum > recvMsg.BlockNum {
consensus.getLogger().Debug("[onViewChange] Message BlockNum Is Low", "MsgBlockNum", recvMsg.BlockNum)
return return
} }
if consensus.blockNum < recvMsg.BlockNum { if consensus.blockNum < recvMsg.BlockNum {
consensus.getLogger().Warn("new leader has lower blocknum", "msgBlock", recvMsg.BlockNum) consensus.getLogger().Warn("[onViewChange] New Leader Has Lower Blocknum", "MsgBlockNum", recvMsg.BlockNum)
return return
} }
if consensus.mode.Mode() == ViewChanging && consensus.mode.GetViewID() > recvMsg.ViewID { if consensus.mode.Mode() == ViewChanging && consensus.mode.ViewID() > recvMsg.ViewID {
consensus.getLogger().Warn("[onViewChange] ViewChanging ID Is Low", "MyViewChangingID", consensus.mode.ViewID(), "MsgViewChangingID", recvMsg.ViewID)
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Debug("onViewChange Failed to verify sender's signature", "error", err) consensus.getLogger().Debug("[onViewChange] Failed To Verify Sender's Signature", "error", err)
return return
} }
@ -227,10 +235,11 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
preparedMsgs := consensus.pbftLog.GetMessagesByTypeSeq(msg_pb.MessageType_PREPARED, recvMsg.BlockNum) preparedMsgs := consensus.pbftLog.GetMessagesByTypeSeq(msg_pb.MessageType_PREPARED, recvMsg.BlockNum)
preparedMsg := consensus.pbftLog.FindMessageByMaxViewID(preparedMsgs) preparedMsg := consensus.pbftLog.FindMessageByMaxViewID(preparedMsgs)
if preparedMsg == nil { if preparedMsg == nil {
sign := consensus.priKey.SignHash(NIL) consensus.getLogger().Debug("[onViewChange] add my M2(NIL) type messaage")
consensus.nilSigs[consensus.PubKey.SerializeToHexStr()] = sign consensus.nilSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(NIL)
consensus.nilBitmap.SetKey(consensus.PubKey, true) consensus.nilBitmap.SetKey(consensus.PubKey, true)
} else { } else {
consensus.getLogger().Debug("[onViewChange] add my M1 type messaage")
msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...) msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
consensus.bhpSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(msgToSign) consensus.bhpSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(msgToSign)
consensus.bhpBitmap.SetKey(consensus.PubKey, true) consensus.bhpBitmap.SetKey(consensus.PubKey, true)
@ -239,78 +248,78 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
// add self m3 type message signature and bitmap // add self m3 type message signature and bitmap
_, ok3 := consensus.viewIDSigs[consensus.PubKey.SerializeToHexStr()] _, ok3 := consensus.viewIDSigs[consensus.PubKey.SerializeToHexStr()]
if !ok3 { if !ok3 {
viewIDHash := make([]byte, 4) viewIDBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(viewIDHash, recvMsg.ViewID) binary.LittleEndian.PutUint32(viewIDBytes, recvMsg.ViewID)
sign := consensus.priKey.SignHash(viewIDHash) consensus.viewIDSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(viewIDBytes)
consensus.viewIDSigs[consensus.PubKey.SerializeToHexStr()] = sign
consensus.viewIDBitmap.SetKey(consensus.PubKey, true) consensus.viewIDBitmap.SetKey(consensus.PubKey, true)
} }
if len(consensus.viewIDSigs) >= consensus.Quorum() {
return
}
// m2 type message // m2 type message
if len(recvMsg.Payload) == 0 { if len(recvMsg.Payload) == 0 {
_, ok := consensus.nilSigs[senderKey.SerializeToHexStr()] _, ok := consensus.nilSigs[senderKey.SerializeToHexStr()]
if ok { if ok {
consensus.getLogger().Debug("onViewChange already received m2 message from the validator", "validatorPubKey", senderKey.SerializeToHexStr()) consensus.getLogger().Debug("[onViewChange] Already Received M2 message from validator", "validatorPubKey", senderKey.SerializeToHexStr())
return return
} }
if !recvMsg.ViewchangeSig.VerifyHash(senderKey, NIL) { if !recvMsg.ViewchangeSig.VerifyHash(senderKey, NIL) {
consensus.getLogger().Warn("onViewChange failed to verify signature for m2 type viewchange message") consensus.getLogger().Warn("[onViewChange] Failed To Verify Signature For M2 Type Viewchange Message")
return return
} }
consensus.getLogger().Debug("[onViewChange] Add M2 (NIL) type message", "validatorPubKey", senderKey.SerializeToHexStr())
consensus.nilSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig consensus.nilSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig
consensus.nilBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed. consensus.nilBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed.
} else { // m1 type message } else { // m1 type message
_, ok := consensus.bhpSigs[senderKey.SerializeToHexStr()] _, ok := consensus.bhpSigs[senderKey.SerializeToHexStr()]
if ok { if ok {
consensus.getLogger().Debug("onViewChange already received m1 message from the validator", "validatorPubKey", senderKey.SerializeToHexStr()) consensus.getLogger().Debug("[onViewChange] Already Received M1 Message From the Validator", "validatorPubKey", senderKey.SerializeToHexStr())
return return
} }
if !recvMsg.ViewchangeSig.VerifyHash(recvMsg.SenderPubkey, recvMsg.Payload) { if !recvMsg.ViewchangeSig.VerifyHash(recvMsg.SenderPubkey, recvMsg.Payload) {
consensus.getLogger().Warn("onViewChange failed to verify signature for m1 type viewchange message") consensus.getLogger().Warn("[onViewChange] Failed to Verify Signature for M1 Type Viewchange Message")
return return
} }
// first time receive m1 type message, need verify validity of prepared message // first time receive m1 type message, need verify validity of prepared message
if len(consensus.m1Payload) == 0 || !bytes.Equal(consensus.m1Payload, recvMsg.Payload) { if len(consensus.m1Payload) == 0 || !bytes.Equal(consensus.m1Payload, recvMsg.Payload) {
if len(recvMsg.Payload) <= 32 { if len(recvMsg.Payload) <= 32 {
consensus.getLogger().Debug("m1 recvMsg payload not enough length", "len", len(recvMsg.Payload)) consensus.getLogger().Debug("[onViewChange] M1 RecvMsg Payload Not Enough Length", "len", len(recvMsg.Payload))
return return
} }
blockHash := recvMsg.Payload[:32] blockHash := recvMsg.Payload[:32]
aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32) aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32)
if err != nil { if err != nil {
consensus.getLogger().Error("m1 recvMsg payload read error", "error", err) consensus.getLogger().Error("[onViewChange] M1 RecvMsg Payload Read Error", "error", err)
return return
} }
// check has 2f+1 signature in m1 type message // check has 2f+1 signature in m1 type message
if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() { if count := utils.CountOneBits(mask.Bitmap); count < consensus.Quorum() {
consensus.getLogger().Debug("not have enough signature", "need", consensus.Quorum(), "have", count) consensus.getLogger().Debug("[onViewChange] M1 Payload Not Have Enough Signature", "need", consensus.Quorum(), "have", count)
return return
} }
// Verify the multi-sig for prepare phase // Verify the multi-sig for prepare phase
if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) { if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) {
consensus.getLogger().Warn("onViewChange failed to verify multi signature for m1 prepared payload", "blockHash", blockHash) consensus.getLogger().Warn("[onViewChange] failed to verify multi signature for m1 prepared payload", "blockHash", blockHash)
return return
} }
// if m1Payload is empty, we just add one
if len(consensus.m1Payload) == 0 { if len(consensus.m1Payload) == 0 {
consensus.m1Payload = append(recvMsg.Payload[:0:0], recvMsg.Payload...) consensus.m1Payload = append(recvMsg.Payload[:0:0], recvMsg.Payload...)
// create prepared message // create prepared message for new leader
preparedMsg := PbftMessage{MessageType: msg_pb.MessageType_PREPARED, ViewID: recvMsg.ViewID, BlockNum: recvMsg.BlockNum} preparedMsg := PbftMessage{MessageType: msg_pb.MessageType_PREPARED, ViewID: recvMsg.ViewID, BlockNum: recvMsg.BlockNum}
preparedMsg.BlockHash = common.Hash{} preparedMsg.BlockHash = common.Hash{}
copy(preparedMsg.BlockHash[:], recvMsg.Payload[:32]) copy(preparedMsg.BlockHash[:], recvMsg.Payload[:32])
preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32) preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32)
copy(preparedMsg.Payload[:], recvMsg.Payload[32:]) copy(preparedMsg.Payload[:], recvMsg.Payload[32:])
preparedMsg.SenderPubkey = consensus.PubKey preparedMsg.SenderPubkey = consensus.PubKey
consensus.getLogger().Info("new leader prepared message added") consensus.getLogger().Info("[onViewChange] New Leader Prepared Message Added")
consensus.pbftLog.AddMessage(&preparedMsg) consensus.pbftLog.AddMessage(&preparedMsg)
} }
} }
consensus.getLogger().Debug("[onViewChange] Add M1 (prepared) type message", "validatorPubKey", senderKey.SerializeToHexStr())
consensus.bhpSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig consensus.bhpSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig
consensus.bhpBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed. consensus.bhpBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed.
} }
@ -318,18 +327,21 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
// check and add viewID (m3 type) message signature // check and add viewID (m3 type) message signature
_, ok := consensus.viewIDSigs[senderKey.SerializeToHexStr()] _, ok := consensus.viewIDSigs[senderKey.SerializeToHexStr()]
if ok { if ok {
consensus.getLogger().Debug("onViewChange already received m3 viewID message from the validator", "senderKey.SerializeToHexStr()", senderKey.SerializeToHexStr()) consensus.getLogger().Debug("[onViewChange] Already Received M3(ViewID) message from the validator", "senderKey.SerializeToHexStr()", senderKey.SerializeToHexStr())
return return
} }
viewIDHash := make([]byte, 4) viewIDHash := make([]byte, 4)
binary.LittleEndian.PutUint32(viewIDHash, recvMsg.ViewID) binary.LittleEndian.PutUint32(viewIDHash, recvMsg.ViewID)
if !recvMsg.ViewidSig.VerifyHash(recvMsg.SenderPubkey, viewIDHash) { if !recvMsg.ViewidSig.VerifyHash(recvMsg.SenderPubkey, viewIDHash) {
consensus.getLogger().Warn("onViewChange failed to verify viewID signature", "msgViewID", recvMsg.ViewID) consensus.getLogger().Warn("[onViewChange] Failed to Verify M3 Message Signature", "MsgViewID", recvMsg.ViewID)
return return
} }
consensus.getLogger().Debug("[onViewChange] Add M3 (ViewID) type message", "validatorPubKey", senderKey.SerializeToHexStr())
consensus.viewIDSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewidSig consensus.viewIDSigs[senderKey.SerializeToHexStr()] = recvMsg.ViewidSig
consensus.viewIDBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed. consensus.viewIDBitmap.SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed.
consensus.getLogger().Debug("[onViewChange]", "numSigs", len(consensus.viewIDSigs), "needed", consensus.Quorum())
// received enough view change messages, change state to normal consensus
if len(consensus.viewIDSigs) >= consensus.Quorum() { if len(consensus.viewIDSigs) >= consensus.Quorum() {
consensus.mode.SetMode(Normal) consensus.mode.SetMode(Normal)
consensus.LeaderPubKey = consensus.PubKey consensus.LeaderPubKey = consensus.PubKey
@ -339,109 +351,104 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
consensus.ReadySignal <- struct{}{} consensus.ReadySignal <- struct{}{}
}() }()
} else { } else {
consensus.getLogger().Debug("[OnViewChange] Switching phase", "From", consensus.phase, "To", Commit)
consensus.switchPhase(Commit, true) consensus.switchPhase(Commit, true)
copy(consensus.blockHash[:], consensus.m1Payload[:32]) copy(consensus.blockHash[:], consensus.m1Payload[:32])
aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32) aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32)
if err != nil { if err != nil {
consensus.getLogger().Error("readSignatureBitmapPayload fail", "error", err) consensus.getLogger().Error("[onViewChange] ReadSignatureBitmapPayload Fail", "error", err)
return return
} }
consensus.aggregatedPrepareSig = aggSig consensus.aggregatedPrepareSig = aggSig
consensus.prepareBitmap = mask consensus.prepareBitmap = mask
// Leader sign commit message // Leader sign and add commit message
blockNumHash := make([]byte, 8) blockNumBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, consensus.blockNum) binary.LittleEndian.PutUint64(blockNumBytes, consensus.blockNum)
commitPayload := append(blockNumHash, consensus.blockHash[:]...) commitPayload := append(blockNumBytes, consensus.blockHash[:]...)
consensus.commitSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(commitPayload) consensus.commitSigs[consensus.PubKey.SerializeToHexStr()] = consensus.priKey.SignHash(commitPayload)
} }
consensus.mode.SetViewID(recvMsg.ViewID) consensus.mode.SetViewID(recvMsg.ViewID)
msgToSend := consensus.constructNewViewMessage() msgToSend := consensus.constructNewViewMessage()
consensus.getLogger().Warn("[onViewChange] Sent NewView Message", "len(M1Payload)", len(consensus.m1Payload), "M1Payload", consensus.m1Payload)
consensus.getLogger().Warn("onViewChange sent newview message")
consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)) consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend))
consensus.viewID = recvMsg.ViewID consensus.viewID = recvMsg.ViewID
consensus.ResetViewChangeState() consensus.ResetViewChangeState()
consensus.consensusTimeout[timeoutViewChange].Stop() consensus.consensusTimeout[timeoutViewChange].Stop()
consensus.consensusTimeout[timeoutConsensus].Start() consensus.consensusTimeout[timeoutConsensus].Start()
consensus.getLogger().Debug("new leader start consensus timer and stop view change timer", "viewChangingID", consensus.mode.ViewID()) consensus.getLogger().Debug("[onViewChange] New Leader Start Consensus Timer and Stop View Change Timer", "viewChangingID", consensus.mode.ViewID())
consensus.getLogger().Debug("I am the new leader", "myKey", consensus.PubKey.SerializeToHexStr(), "viewID", consensus.viewID, "block", consensus.blockNum) consensus.getLogger().Debug("[onViewChange] I am the New Leader", "myKey", consensus.PubKey.SerializeToHexStr(), "viewID", consensus.viewID, "block", consensus.blockNum)
} }
consensus.getLogger().Debug("onViewChange", "numSigs", len(consensus.viewIDSigs), "needed", consensus.Quorum())
} }
// TODO: move to consensus_leader.go later // TODO: move to consensus_leader.go later
func (consensus *Consensus) onNewView(msg *msg_pb.Message) { func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
consensus.getLogger().Debug("onNewView received new view message") consensus.getLogger().Debug("[onNewView] Received NewView Message")
senderKey, err := consensus.verifyViewChangeSenderKey(msg) senderKey, err := consensus.verifyViewChangeSenderKey(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onNewView verifySenderKey failed", "error", err) consensus.getLogger().Warn("[onNewView] VerifySenderKey Failed", "error", err)
return return
} }
recvMsg, err := consensus.ParseNewViewMessage(msg) recvMsg, err := consensus.ParseNewViewMessage(msg)
if err != nil { if err != nil {
consensus.getLogger().Warn("onViewChange unable to parse viewchange message") consensus.getLogger().Warn("[onNewView] Unable to Parse NewView Message", "error", err)
return return
} }
if err = verifyMessageSig(senderKey, msg); err != nil { if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Error("onNewView failed to verify new leader's signature", "error", err) consensus.getLogger().Error("[onNewView] Failed to Verify New Leader's Signature", "error", err)
return return
} }
consensus.vcLock.Lock() consensus.vcLock.Lock()
defer consensus.vcLock.Unlock() defer consensus.vcLock.Unlock()
if recvMsg.M3AggSig == nil || recvMsg.M3Bitmap == nil { if recvMsg.M3AggSig == nil || recvMsg.M3Bitmap == nil {
consensus.getLogger().Error("onNewView M3AggSig or M3Bitmap is nil") consensus.getLogger().Error("[onNewView] M3AggSig or M3Bitmap is nil")
return return
} }
m3Sig := recvMsg.M3AggSig m3Sig := recvMsg.M3AggSig
m3Mask := recvMsg.M3Bitmap m3Mask := recvMsg.M3Bitmap
viewIDHash := make([]byte, 4)
binary.LittleEndian.PutUint32(viewIDHash, recvMsg.ViewID) viewIDBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(viewIDBytes, recvMsg.ViewID)
// check total number of sigs >= 2f+1 // check total number of sigs >= 2f+1
if count := utils.CountOneBits(m3Mask.Bitmap); count < consensus.Quorum() { if count := utils.CountOneBits(m3Mask.Bitmap); count < consensus.Quorum() {
consensus.getLogger().Debug("not have enough signature", "need", consensus.Quorum(), "have", count) consensus.getLogger().Debug("[onNewView] Not Have Enough M3 (ViewID) Signature", "need", consensus.Quorum(), "have", count)
return return
} }
if !m3Sig.VerifyHash(m3Mask.AggregatePublic, viewIDHash) { if !m3Sig.VerifyHash(m3Mask.AggregatePublic, viewIDBytes) {
consensus.getLogger().Warn("onNewView unable to verify aggregated signature of m3 payload", "m3Sig", m3Sig.SerializeToHexStr(), "m3Mask", m3Mask.Bitmap, "msgViewID", recvMsg.ViewID) consensus.getLogger().Warn("[onNewView] Unable to Verify Aggregated Signature of M3 (ViewID) payload", "m3Sig", m3Sig.SerializeToHexStr(), "m3Mask", m3Mask.Bitmap, "MsgViewID", recvMsg.ViewID)
return return
} }
m2Mask := recvMsg.M2Bitmap m2Mask := recvMsg.M2Bitmap
if recvMsg.M2AggSig != nil { if recvMsg.M2AggSig != nil {
consensus.getLogger().Debug("[onNewView] M2AggSig (NIL) is Not Empty")
m2Sig := recvMsg.M2AggSig m2Sig := recvMsg.M2AggSig
if !m2Sig.VerifyHash(m2Mask.AggregatePublic, NIL) { if !m2Sig.VerifyHash(m2Mask.AggregatePublic, NIL) {
consensus.getLogger().Warn("onNewView unable to verify aggregated signature of m2 payload") consensus.getLogger().Warn("[onNewView] Unable to Verify Aggregated Signature of M2 (NIL) payload")
return return
} }
} }
if m3Mask == nil || m3Mask.Bitmap == nil {
consensus.getLogger().Error("onNewView m3Mask or m3Mask.Bitmap is nil")
return
}
// check when M3 sigs > M2 sigs, then M1 (recvMsg.Payload) should not be empty // check when M3 sigs > M2 sigs, then M1 (recvMsg.Payload) should not be empty
if m2Mask == nil || m2Mask.Bitmap == nil || (m2Mask != nil && m2Mask.Bitmap != nil && utils.CountOneBits(m3Mask.Bitmap) > utils.CountOneBits(m2Mask.Bitmap)) { if m2Mask == nil || m2Mask.Bitmap == nil || (m2Mask != nil && m2Mask.Bitmap != nil && utils.CountOneBits(m3Mask.Bitmap) > utils.CountOneBits(m2Mask.Bitmap)) {
if len(recvMsg.Payload) <= 32 { if len(recvMsg.Payload) <= 32 {
consensus.getLogger().Debug("we should have m1 message payload non-empty and valid") consensus.getLogger().Debug("[onNewView] M1 (prepared) Type Payload Not Have Enough Length")
return return
} }
// m1 is not empty, check it's valid // m1 is not empty, check it's valid
blockHash := recvMsg.Payload[:32] blockHash := recvMsg.Payload[:32]
aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32) aggSig, mask, err := consensus.readSignatureBitmapPayload(recvMsg.Payload, 32)
if err != nil { if err != nil {
consensus.getLogger().Error("unable to read signature/bitmap", "error", err) consensus.getLogger().Error("[onNewView] ReadSignatureBitmapPayload Failed", "error", err)
return return
} }
if !aggSig.VerifyHash(mask.AggregatePublic, blockHash) { if !aggSig.VerifyHash(mask.AggregatePublic, blockHash) {
consensus.getLogger().Warn("onNewView failed to verify signature for prepared message") consensus.getLogger().Warn("[onNewView] Failed to Verify Signature for M1 (prepare) message")
return return
} }
copy(consensus.blockHash[:], blockHash) copy(consensus.blockHash[:], blockHash)
@ -466,10 +473,11 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
// change view and leaderKey to keep in sync with network // change view and leaderKey to keep in sync with network
if consensus.blockNum != recvMsg.BlockNum { if consensus.blockNum != recvMsg.BlockNum {
consensus.getLogger().Debug("new leader changed", "newLeaderKey", consensus.LeaderPubKey.SerializeToHexStr(), "msgBlock", recvMsg.BlockNum) consensus.getLogger().Debug("[onNewView] New Leader Changed", "newLeaderKey", consensus.LeaderPubKey.SerializeToHexStr(), "MsgBlockNum", recvMsg.BlockNum)
return return
} }
// NewView message is verified, change state to normal consensus
if len(recvMsg.Payload) > 32 { if len(recvMsg.Payload) > 32 {
// Construct and send the commit message // Construct and send the commit message
blockNumHash := make([]byte, 8) blockNumHash := make([]byte, 8)
@ -479,6 +487,7 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
consensus.getLogger().Info("onNewView === commit") consensus.getLogger().Info("onNewView === commit")
consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend)) consensus.host.SendMessageToGroups([]p2p.GroupID{p2p.NewGroupIDByShardID(p2p.ShardID(consensus.ShardID))}, host.ConstructP2pMessage(byte(17), msgToSend))
consensus.getLogger().Debug("[OnViewChange] Switching phase", "From", consensus.phase, "To", Commit)
consensus.switchPhase(Commit, true) consensus.switchPhase(Commit, true)
} else { } else {
consensus.ResetState() consensus.ResetState()

@ -27,7 +27,7 @@ const (
// GenesisShardSize is the size of each shard at genesis // GenesisShardSize is the size of each shard at genesis
GenesisShardSize = 100 GenesisShardSize = 100
// GenesisShardHarmonyNodes is the number of harmony node at each shard // GenesisShardHarmonyNodes is the number of harmony node at each shard
GenesisShardHarmonyNodes = 76 GenesisShardHarmonyNodes = 75
// CuckooRate is the percentage of nodes getting reshuffled in the second step of cuckoo resharding. // CuckooRate is the percentage of nodes getting reshuffled in the second step of cuckoo resharding.
CuckooRate = 0.1 CuckooRate = 0.1
) )

@ -89,6 +89,12 @@ func (dRand *DRand) ProcessMessageLeader(payload []byte) {
utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand) utils.GetLogInstance().Error("Failed to unmarshal message payload.", "err", err, "dRand", dRand)
} }
if message.GetDrand().ShardId != dRand.ShardID {
utils.GetLogInstance().Warn("Received drand message from different shard",
"myShardId", dRand.ShardID, "receivedShardId", message.GetDrand().ShardId)
return
}
switch message.Type { switch message.Type {
case msg_pb.MessageType_DRAND_COMMIT: case msg_pb.MessageType_DRAND_COMMIT:
dRand.processCommitMessage(message) dRand.processCommitMessage(message)

@ -19,6 +19,7 @@ func (dRand *DRand) constructInitMessage() []byte {
drandMsg := message.GetDrand() drandMsg := message.GetDrand()
drandMsg.SenderPubkey = dRand.pubKey.Serialize() drandMsg.SenderPubkey = dRand.pubKey.Serialize()
drandMsg.BlockHash = dRand.blockHash[:] drandMsg.BlockHash = dRand.blockHash[:]
drandMsg.ShardId = dRand.ShardID
// Don't need the payload in init message // Don't need the payload in init message
marshaledMessage, err := dRand.signAndMarshalDRandMessage(message) marshaledMessage, err := dRand.signAndMarshalDRandMessage(message)
if err != nil { if err != nil {

@ -19,7 +19,7 @@ func (dRand *DRand) constructCommitMessage(vrf [32]byte, proof []byte) []byte {
drandMsg := message.GetDrand() drandMsg := message.GetDrand()
drandMsg.SenderPubkey = dRand.pubKey.Serialize() drandMsg.SenderPubkey = dRand.pubKey.Serialize()
drandMsg.BlockHash = dRand.blockHash[:] drandMsg.BlockHash = dRand.blockHash[:]
drandMsg.BlockHash = dRand.blockHash[:] drandMsg.ShardId = dRand.ShardID
drandMsg.Payload = append(vrf[:], proof...) drandMsg.Payload = append(vrf[:], proof...)
// Adding the public key into payload so leader can verify the vrf // Adding the public key into payload so leader can verify the vrf
// TODO: change the curve to follow the same curve with consensus, so the public key doesn't need to be attached. // TODO: change the curve to follow the same curve with consensus, so the public key doesn't need to be attached.

@ -2,103 +2,104 @@ package genesis
// GenesisFNAccounts are the ECSDA accounts for the foundational nodes. // GenesisFNAccounts are the ECSDA accounts for the foundational nodes.
var GenesisFNAccounts = [...]DeployAccount{ var GenesisFNAccounts = [...]DeployAccount{
{Index: "0", Address: "one1djwg5f0l3ccnscupqz6htcqsjnl85jt8xvpwhc", BlsPriKey: "8aa6f004ebcad760786f40db57c03b78a7d900592a1924bf432d086cac8ca70d", BlsPublicKey: "a6b13915d0022705b91dfe8e9cf07e4dceff0d273eb979d0236f51d438eccc33d2cb1a2c4405d86c798c192ed7447f0b"}, {Index: "0", Address: "one1y0xcf40fg65n2ehm8fx5vda4thrkymhpg45ecj", BlsPriKey: "6e4c9bb993e6eb1c59947960f866047e002ab513fe80f303f2f6253ac00cf960", BlsPublicKey: "9e70e8d76851f6e8dc648255acdd57bb5c49cdae7571aed43f86e9f140a6343caed2ffa860919d03e0912411fee4850a", Updated: "copied from sheet"},
{Index: "1", Address: "one1q563tnpv4tnh7l30p2wy3gnu3akhd6va97w7ku", BlsPriKey: "ab7bacb618d8153eac3fbe97e5b06c9ac3980af12659ce37392771de85c1b36a", BlsPublicKey: "490bbab0b339c3e64e02c7e646dc2243e2c291f89408dbc61afb3e55cbfed6f70f6528f752b95dc11ca0ac47aaffed13"}, {Index: "1", Address: "one1q563tnpv4tnh7l30p2wy3gnu3akhd6va97w7ku", BlsPriKey: "df29ffd990d798f08afcc2e7a8225f3a7e44d62ef3a4c17dc7fd1586d17ed627", BlsPublicKey: "4cb81c627f179a67085ed9fc80f851ea357debad60ebaaca7e8e091a54efd1ca5849094524aa55527b0c173530b1c392", Updated: "was in code and updated from sheet"},
{Index: "2", Address: "0x04c3636dF766ad2d3E74424c016842f5704FAE3A", BlsPriKey: "1206de176f084343714a3dd77777b30ecffeccf4bd80cdb97b30b1f6cf5a5d39", BlsPublicKey: "ae66c9e16d52cbb799fbe2e7c706cff245a705c1c9819f538f7d686c2337632936aac68c88f6b0e8bfe1e3b90fd0d708"}, {Index: "2", Address: "one18lp2w7ghhuajdpzl8zqeddza97u92wtkfcwpjk", BlsPriKey: "6205462fb43e2d6514fee923a0afb18b41d7345b70e6dbd7955061681d2e560f", BlsPublicKey: "fce3097d9fc234d34d6eaef3eecd0365d435d1118f69f2da1ed2a69ba725270771572e40347c222aca784cb973307b11", Updated: "copied from sheet"},
{Index: "3", Address: "one1pz4c0uagav9kn2pn2adkgqr8pulnxqcz4nmvax", BlsPriKey: "4d5a65fe77301924ac56f591ef59bef1578f9fbdde98e5f3d54e43a5a1f7f76b", BlsPublicKey: "32f4a18b121c16b1c26742728fdc1f2738b49fba066b3e280d213db1a02130857da68ac72b15e2667c49b9f8ce6a318c"}, {Index: "3", Address: "one1pz4c0uagav9kn2pn2adkgqr8pulnxqcz4nmvax", BlsPriKey: "2ded27f361ae35e745e2144fcdd349b82d6791f10ad017b9ca588a8f28177218", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "was in code and updated from sheet"},
{Index: "4", Address: "one1ldthk5zyrea6w60rptcfyzlftd8fsn9fhkeps7", BlsPriKey: "9923a30374a16d12e59c8431500cab38b672dec68d0dc024ea873a41707a7c36", BlsPublicKey: "dd001ad10adbebabfe4777632074885dc188f6b4e1760281ee5fd84e23e969733d803091de350e581e2c10d2c229568c"}, {Index: "4", Address: "one1ldthk5zyrea6w60rptcfyzlftd8fsn9fhkeps7", BlsPriKey: "11f7fa746112d7a2485d29b572f115a0d3f20e9b4117c927a73d2e5347246f1c", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "was in code and updated from sheet"},
{Index: "5", Address: "0x144B2Fd168147311f749B0f9573664676C333e2A", BlsPriKey: "e0731ed35d334fddd7dc347520025b00df3490dc3e796065da4cf11d51dc1602", BlsPublicKey: "ef0c6690395cb8006ff2a68c32624d4666c2e764e4210437acb28a9421a304bc019e485a38787af1e8cd8f5eb3e02c94"}, {Index: "5", Address: "one1z39jl5tgz3e3ra6fkru4wdnyvakrx0323zyr8v", BlsPriKey: "0e6ea9aec01fa4d78433797a0162b8134b1f16435e7233799c3319a49a623a1e", BlsPublicKey: "0e8ce22d33fd39b74e6ebe72f037dd575d82d779a339557369fc65eec6db2dd14c1989ba786f5e6fbd13b9aa5eaea903", Updated: "was in code and updated from sheet"},
{Index: "6", Address: "0x22117D26611161b1b1f4EBB06C441aeeA102261c", BlsPriKey: "2b1c8cc86afdd7b78b02a44693949433731e7fc4e44b125cdb27db24e12b7024", BlsPublicKey: "dbcbc15f09f2c9419cd0df3af51f37febe51522b6d7937f646c1b5a28e6c9700b8da093237a5ef18538ca96069995819"}, {Index: "6", Address: "one19y2r8ykaztka3z8ndea0a2afd5kgswyfeahsmf", BlsPriKey: "732747c5ab1552bcbb4cfdbe87e72719496f7a0c581f08dfc0af5760c695c35b", BlsPublicKey: "475b5c3bbbda60cd92951e44bbea2aac63f1b774652d6bbec86aaed0dabd10a46717e98763d559b63bc4f1bfbde66908", Updated: "copied from sheet"},
{Index: "7", Address: "one1zvaqqafg0nvmxtsvzkqalc3lz378qw5j6ysz5l", BlsPriKey: "c129ecdd4a66e67cfd5b51199c8383adef8d23f718e85e1882e389d5e78f625f", BlsPublicKey: "e9a4e069fb4ef2b89c003c7bcbf27d5c94ed0c1199bedb6383c6fb086fca046080e0e380d3c9278d156a1711296b5708"}, {Index: "7", Address: "one1zvaqqafg0nvmxtsvzkqalc3lz378qw5j6ysz5l", BlsPriKey: "527cf719d7ee215e0b22ea8778d86b01701ba2378db916dd8cf50bdfe1294d38", BlsPublicKey: "829246b61310fc6d48de362ba51c85764b0e4e594f38fb21fa14df203dbabcbc1c45e2c53d5d06677a1d6dce3cdcb282", Updated: "was in code and updated from sheet"},
{Index: "8", Address: "one1y5686zfh8vnygxglrhztahh7hcn2tvk33vsgrt", BlsPriKey: "56a84cb496c6f616f30ea82682996da188da6a40e8ec897bd36d5c8a7ff32d47", BlsPublicKey: "8a17f4b2cb0f202b4d68937cc66213c372c0f1f339bde555270556fd86d41b58c13945a734682da8b0111be870e11404"}, {Index: "8", Address: "one1y5686zfh8vnygxglrhztahh7hcn2tvk33vsgrt", BlsPriKey: "0c7d3eb1276f19a443fdac60dded4791a4a55ce49b6019dcf58c704a2222b65e", BlsPublicKey: "ed59468d36e33f0e2cd21951c55e41420a6736d23ef013eb3a39f6b4a9290c6353c0a3ea996bc5ae65bd4a5776f76c96", Updated: "was in code and updated from sheet"},
{Index: "9", Address: "0x25441821ecA41DEc79578aAB866d3627A2e9BB9f", BlsPriKey: "373dcdfc1824dec533b2f76eafa7254ebda9348b6fd6ee6841bc22655fb3a93e", BlsPublicKey: "c7577b13ee856a32c1a04f703c0a154d2a8095a94ae035b2ac8f91cda61986ec2bdd87d10c91726a9ca9ed6eb884fa19"}, {Index: "9", Address: "one1nvu626slwt6hwq2cup846nepcl2apuhk38gl3j", BlsPriKey: "0ad522a8f261ff061ed9b26c21e00b5d6df890589b51234cda265d99f5f1965a", BlsPublicKey: "663f82d48ff61d09bb215836f853e838df7da62aa90344dcf7950c18378dae909895c0c179c2dd71ea77fa747af53106", Updated: "copied from sheet"},
{Index: "10", Address: "one1y7fs65ul4zc33d2502ql6nxs7r7jj4grs5x3y9", BlsPriKey: "e79a37317e6f27909ac65b19726165e59f676f06a94a487b5c46821e0f30273e", BlsPublicKey: "d522ebf196ec2dd40b90cc76a0b9d8ba3ceadda698d68ea3901da73078c753aa2609f3465f67c533f719617d1673e814"}, {Index: "10", Address: "one1y7fs65ul4zc33d2502ql6nxs7r7jj4grs5x3y9", BlsPriKey: "1aaa0e30b6f746f048df8f67ac0c7a89995aeb93de83ab76946b61c6a6792619", BlsPublicKey: "847ba7e5422187c2c0e594efa31840d117641d9a156ffc076d9194ab71f7ce95b59f2c00a822312da60f39f2d6437583", Updated: "was in code and updated from sheet"},
{Index: "11", Address: "one19qy96szsrhuyjfrqgr4gzhaaw8cgct7ym83wy3", BlsPriKey: "335a2cc6851d8f64bb06c41e619e924e3f9f75fe715782a33e4017387e9e7a12", BlsPublicKey: "22ad933ef047430172727250643b2f15d3e52d4a1a134d5e6e7e7beda2c771934a9c1f3d2b32dfafe11290572394348c"}, {Index: "11", Address: "one19qy96szsrhuyjfrqgr4gzhaaw8cgct7ym83wy3", BlsPriKey: "f201abb3a8291bf493be41e90deed45daefb6a819af5f00c37d2a1d4da49ed3e", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "was in code and updated from sheet"},
{Index: "12", Address: "0x28dA1beF8F5361863DcD427B6264f9DdF05B5D14", BlsPriKey: "22fe4ec2e86ad1f181233734f0e2364a029b5cfde28cf0013fe20c0ea567cf46", BlsPublicKey: "39797b3efb0f62ddc12b8322308fbe19e5890e6c80e9f214bda693b0931e3bf6d9d01a31f86cc886bb15965e3ced9903"}, {Index: "12", Address: "one16y3pzva57c65wwfpwr7ve63q67aztedsphv069", BlsPriKey: "7127c7cf52ecd156ffe247134c0820f6b9e33a4349c52b21600b6d8a25702345", BlsPublicKey: "1e9f5f68845634efca8a64e8ffcf90d63ec196f28fb64f688fb88b868728ab562b702af8414f48c5d045e94433ec5a87", Updated: "copied from sheet"},
{Index: "13", Address: "one12zelq8ax3k48tfzl5zz37ndknremq6um62dwxa", BlsPriKey: "38406f54995917aaee1387b228f4d14ecaa7e0b94b59ca41f6caf6364fb8a92d", BlsPublicKey: "bd69b3b3b029269af6c001c101cd3e086c33aeb3f1a12d04bfacbd8a1ea8906506238bff9a86635f198c012c07fa2805"}, {Index: "13", Address: "one12zelq8ax3k48tfzl5zz37ndknremq6um62dwxa", BlsPriKey: "454196dfa2954d7bb84f2d5f44661708f418b1bd321818e976bda406f58e9f1c", BlsPublicKey: "0171f68b35f45281222ff9008d40301d20fb5c328fd8126cf24f50f15b879b818c14b4f98b58ad7864cb75509993190b", Updated: "was in code and updated from sheet"},
{Index: "14", Address: "one19verfm5jyu9ys6s4nrzm6a8888kzdlvmqpenh4", BlsPriKey: "1b4054a787c7be928b3d479b18698dc131e14d51b059eee29e573b9673ab6a0d", BlsPublicKey: "7ff3beba14d2b33e4450b08fb16bdf2a3f7f4d7a01cbfdfa627962205fdd6ca4116883a2f1b5e34aa834c404b3a9d210"}, {Index: "14", Address: "one19verfm5jyu9ys6s4nrzm6a8888kzdlvmqpenh4", BlsPriKey: "c432402edfc55ca7ec91adf91d830481e329513500303ca4a49a98c8b5cf9504", BlsPublicKey: "7fb7ccadd6fa57a04fa49e6128063fc003dfc543688a1dcb15546ffe9e180467f85f0b3aa0382472f27a2e0db050ed09", Updated: "was in code and updated from sheet"},
{Index: "15", Address: "0x2bC858D0967384C0093e12824Bb3d6486d51c30D", BlsPriKey: "db3d204469d35d5d5643b04891e949da47211815be38272a5508d5130cb33b19", BlsPublicKey: "62b61aac6cdf0ee6948607baa6468d5055ce3aa77fd2a2aa424aad0c86c951e555ba3f9f2124f6d1aa26126be5b9b794"}, {Index: "15", Address: "one14uzsrvucmxx5wwkx46r9a6mpqgtjlrchelw5pp", BlsPriKey: "6787e0bb328a2f29e58037ada6b2f2324b2cf39ab04f865dcb43526f1b155819", BlsPublicKey: "43b1376eff41dfdccaeb601edc09b4353e5abd343a90740ecb3f9aac882321361e01267ffd2a0e2115755b5148b1f115", Updated: "copied from sheet"},
{Index: "16", Address: "0x324c741430F5B970b61E398434B4F3957a6BC6E0", BlsPriKey: "026217bf9c1f3407be9908d9e2d5552974d0a71f6bf8bed798934c9e38e7040b", BlsPublicKey: "1b952b337143f7c6bdb2232183ca8fe73edaf7046f5d67a3d28a2b76b0f865d0c1bcdbcb97fa3eff8881b6581776db0e"}, {Index: "16", Address: "one1pmcysk3kctszln8n89hzcrgmncnqcdxg6nl2gg", BlsPriKey: "4380ec6b1d4a5ce55d405600c97168b3ac77c996bee12c118b1c8f8260cf582b", BlsPublicKey: "43f5ed2b60cb88c64dc16c4c3527943eb92a15f75967cf37ef3a9a8171da5a59685c198c981a9fd471ffc299fe699887", Updated: "copied from sheet"},
{Index: "17", Address: "0x3413e7e39eE7394b692FB04c12f5671d5Bb43e0b", BlsPriKey: "40a449d4e3257db51fc6f96aad817fcf183f73196c0863e65da5a93d22bc4404", BlsPublicKey: "67b89af10aea52527461de5fff5a782b566ac82cbd73fd417b84814664fc2af1beaad7b14583c05dbd751fd7b8a8f696"}, {Index: "17", Address: "one1xsf70cu7uuu5k6f0kpxp9at8r4dmg0sttzx40t", BlsPriKey: "a9d6f055a98302703a303010a102d2a3133e35a60ff48fe98b95deb6234f462e", BlsPublicKey: "577bac828dacca2acf29f8d38365a5af015b88298482c38f09ccde44f3c1a2d7011f710c4a7fe450d8b5d4e7a6950a05", Updated: "was in code and updated from sheet"},
{Index: "18", Address: "one14tdlgysvnqcdgwnduttd0y5pp2y7m8cpss30j4", BlsPriKey: "c4cd2b4ac8dfec644c18d48b3336fac36cabe42681ca092dc8fa0a6cc56f7838", BlsPublicKey: "85c31b7c664e0e6c6128aee2e0b9755bbc1c31fbf19696f066eedc2bdf2f1116b91fa33fb4865a8577133239b3953307"}, {Index: "18", Address: "one14tdlgysvnqcdgwnduttd0y5pp2y7m8cpss30j4", BlsPriKey: "543f6f3718404155529a35a0291a6bb8f9d70ad887d3f5b3703e3c5a00f1410e", BlsPublicKey: "4ce4d4c2f2a4e115d5c2253a4d5d17c8fb4a585280eda890983309595b2bbb596ec71284105c67618f1fb2e7f7cb6f84", Updated: "was in code and updated from sheet"},
{Index: "19", Address: "one180mfv4dneefp9g74duxhspjvkmcjffstd0sj6q", BlsPriKey: "5d8d7b2d0927ca11f875b64f4e2ba03765bd1a32c1e4ba15dcddcb835d3bd142", BlsPublicKey: "8e6d0d638a2e24273820e7d34ede16df3e2ca6deaec6077be7de09f4d681b80149a5c427b239c6741952eda05d48fc07"}, {Index: "19", Address: "one180mfv4dneefp9g74duxhspjvkmcjffstd0sj6q", BlsPriKey: "f6464c7429f588e2a5d2aeeab832c1b23799f65aac80e847557da2a77fd5cc28", BlsPublicKey: "714fb47f27b4d300320e06e37e973e0a9cfa647f7bdb915262d7fe500252a777f37d8d358dc07b27c7eef88a7521ad06", Updated: "was in code and updated from sheet"},
{Index: "20", Address: "0x3D88FF444D18F7bcC530F5f5171048e725AEc79C", BlsPriKey: "21eb5e459af4edcaba6115dd33bf6cc54e254e084ed996f5628103232daece35", BlsPublicKey: "a70897e23d96968b96461d7173567fe0dca70dcad6779c6e064c3734f89a1f43e8bca67f002dbd1bbd8120d5fa6b0d86"}, {Index: "20", Address: "one18ky073zdrrmme3fs7h63wyzguuj6a3uukuc3gk", BlsPriKey: "143c8b169a677ae032190d96d1ed7a0b17bf0ab9bd92d9505baa0f7f78c02309", BlsPublicKey: "457e99a40be9356c4acc53f02de4480927e0c6c0733087a46f53b59744affb2776700625370c09bf4e778e715a5f6e8a", Updated: "was in code and updated from sheet"},
{Index: "21", Address: "one1grt0frrmy7a8239sg3tygh83nd5q74yymq2ljh", BlsPriKey: "94b5e20b507cdf0dd83b45b39aa5ca43d0d9c50cae98c4d0d03630cc89c6186b", BlsPublicKey: "4415ec6aebb815630cf5e9086c9afea2f9d130562fba8f7989a5238e9469bffdf72a62ef6b967259bc13538b9c645599"}, {Index: "21", Address: "one1grt0frrmy7a8239sg3tygh83nd5q74yymq2ljh", BlsPriKey: "9862b47ef50f2ae9751a743f9c4428294c31bf02d4a5184251f7626ff6087a67", BlsPublicKey: "7e86af118409e2677ab7c3043cd383e98a8ae27bf711eaa57782f7e8e9df5499085dc5ae3e7acc0c4cb362dc6005ab81", Updated: "was in code and updated from sheet"},
{Index: "22", Address: "0x43bcBa1c3c3Bf76790d04cad7357229ECD71BDAD", BlsPriKey: "0875674d61ae1998354c2b5c83e2658d520fea36ec72c4d9270bab4521e1786a", BlsPublicKey: "3df7878a952e72f48c1ebacb91ab688be9bebdff48c2c023527ce8c92faf27d506b4bda0fa7fca7b5c234727383c8798"}, {Index: "22", Address: "one17nfgz8rtgpl3nlws5q9tdk9y3puyqf847az6ne", BlsPriKey: "36df31f96a73bc544e77047c5e8b44fad88536c2c1ab115b090ca08baf47e967", BlsPublicKey: "a32c1ba4c89ce5efe3d5756952489f7050bb1123fe38776168b349c01d15813520f87741a24bdba4372caa71096fb308", Updated: "copied from sheet"},
{Index: "23", Address: "0x52D77E90caE790ad2bA9DE138Ea8B65cCC5EF652", BlsPriKey: "dfca5c00c1e74eaf2bb0cac9fad1ea8b6b98f9076268781c2e15bbe4fece3c55", BlsPublicKey: "24294568ad306b463e0aa5351078de9e34f26be314036beee90ccbe415e47c8d6754d329d3f5cd90e14432543926bb8f"}, {Index: "23", Address: "one12tthayx2u7g262afmcfca29ktnx9aajjd8uj5j", BlsPriKey: "e25738909ac68cf0d24939b916d887336ebb51d717cc52fc91728e53c086f722", BlsPublicKey: "bf1899cd9eab89216cbaed1d126f8b2f6b482132787f0d34020cfe8fdf0af8aff2c38b9848c3726745bbdeebd7d6bf96", Updated: "was in code and updated from sheet"},
{Index: "24", Address: "one1tqa46jj9ut8zu20jm3kqv3f5fwkeq964t496mx", BlsPriKey: "fe1ea84a83b79f878d06ee8d85c05acd4219d6c12c3dd7f7f52893d2bfe24440", BlsPublicKey: "942c811275d09ef1ead1a758033bb8f9921d99931fe0772e1107aa9b5f36773738b6afedc33731e03e7435402346c018"}, {Index: "24", Address: "one1tqa46jj9ut8zu20jm3kqv3f5fwkeq964t496mx", BlsPriKey: "aabea27114663edf6d9c9858335a006fd4062aedff850609d95eb4b8a20a782c", BlsPublicKey: "edb61007e99af30191098f2cd6f787e2f53fb595bf63fcb4d31a386e7070f7a4fdcefd3e896080a665dc19fecbafc306", Updated: "was in code and updated from sheet"},
{Index: "25", Address: "0x6EAe9438B240EdD83f454cc5EcDcbB10719E4e51", BlsPriKey: "e89647432ff31ed7e14e153c233c896f0e10d726038f9802651a01631de26652", BlsPublicKey: "738a8f6b3156e159c225df11cce80651276d85e6452313ea8399a1391519fb2ce4d15dfc7e643468fe525f1487d38a90"}, {Index: "25", Address: "one16f3f9y4sqtrk3eq7gnagr4ac8p25rf08u0pxxp", BlsPriKey: "76608b9c7ddf8cfef53e3dcd825c099e473b854a1b7a378e5a685ba96c3f5f3c", BlsPublicKey: "bde72966189e7377a4f08fff82058fcc508ce1f7778e89c3dab42064bc489e0966c6371f4b1a1857cfea19667346b010", Updated: "copied from sheet"},
{Index: "26", Address: "0x59ebA70c8D8B3d4157432815c2A2DA774bA63aa8", BlsPriKey: "8994215377f865b6669b7542d80c2bf3df8aee632c6392e3fcc1ba60ac97dd38", BlsPublicKey: "dfdc09ee92c4b474377816f06401ee5e708830281c95d1b4c66f3cb77d36c4ad6515aa20f5aea84a1b159c80623cdc8b"}, {Index: "26", Address: "one1zgmd5s6fyv9rm2vuf3augqf3ucnp9a2j0h09u3", BlsPriKey: "bd00de690c82e5a3cb27133cf1b083cab279487a96679bf8ed93b1e5cab13300", BlsPublicKey: "15efd5a3af35b9fca2b0e7264b585b47b0f08d9658ac11df3ee5237be634d2fbfa610bf9bd8eef5fecb38828e250340d", Updated: "copied from sheet"},
{Index: "27", Address: "one1teymhzlyuxv73hw78gy7vlfuyv3e4stvsmer5l", BlsPriKey: "0164833a1e8f2447c415d971494bd9ece1b07e87b2b436edaae2b9ee29901c6b", BlsPublicKey: "a9807a65f3b561838f68ac30851c50af07eb2242ac073915f147f49a26a3517f4e6c141834632bad912f5fdadf564a99"}, {Index: "27", Address: "one1teymhzlyuxv73hw78gy7vlfuyv3e4stvsmer5l", BlsPriKey: "7ba0adcdf7b715aa71f09bee0a90fc20318341760c4d8c271c0d7b9d0b3fcd12", BlsPublicKey: "6b3469bfd08d2a690f731f97d679e15ff565d4f2911f5875f058062239109ba1e3c5a73bfb21b034db9b28ae3f564001", Updated: "was in code and updated from sheet"},
{Index: "28", Address: "one1thzdvxjya045z4ysyy6z52gt6unxyw3c2wzjrr", BlsPriKey: "a428e56b14b2f8c7d3638a394d84915a21f529dcc77caead3e11867db3c79329", BlsPublicKey: "b9c9643f2cc878f5751872cab81688d36332a31db05afaf0fe28c92b1eff4be0d1fb955e01d12f285f5e658454651a02"}, {Index: "28", Address: "one1thzdvxjya045z4ysyy6z52gt6unxyw3c2wzjrr", BlsPriKey: "133dd59cdcee03f41094311d99cffa984297be8b915c7a12860b4076087bb527", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "was in code and updated from sheet"},
{Index: "29", Address: "one12saruhnv9f63dqhuadjq3vhqm3nwyw2ac40uyz", BlsPriKey: "2402ff7eb99d84e84a8f1fcfbc6e158e02314afa6780e4d9a9f135bdda6ec956", BlsPublicKey: "6f65f249dc5d7b2c25af9b88b38ef43cf655ef9687471164e6be962a6280aff40a8dba8145ba34076dda1f37f6700c00"}, {Index: "29", Address: "one12saruhnv9f63dqhuadjq3vhqm3nwyw2ac40uyz", BlsPriKey: "39f8b1764f22cda0d355f82e6282572519c8e158b97cf903ac8c64b7433ca26b", BlsPublicKey: "b443ad07d019e1ab4c1cf8d18d493f34003a6e22d28b79218ed77d072925deb852bf74488bff67ca0126738aaf58e08e", Updated: "was in code and updated from sheet"},
{Index: "30", Address: "0x638Ff0c3c291eA08c2653Bb993E3360D63038678", BlsPriKey: "89da0b21b3efa371b70fb4507c14d995830fd6c46a341cf613ef56df0990ac42", BlsPublicKey: "9f9425878f9824c07ad4609078c92d0552f498786071624addf2f244d5e4a682346f5a6bb8a52cc9a248a763c7534b01"}, {Index: "30", Address: "one10dw0xnkm6qvpmsmeszw5wn29et9jmek9sc6dmw", BlsPriKey: "9aa34ef10f2da52a7d3418e56f56d4b38cd1fe8b6562df16196fcb4497d0af6b", BlsPublicKey: "3f9c6d55095433092416ed39bcac4fb1c7aee67f7b658c09266201a094708f7101ae8dfdddca13ed3021ca798f731992", Updated: "copied from sheet"},
{Index: "31", Address: "0xD61e36c14D6679D6c93baB5Dc754EdA20Ebc64DA", BlsPriKey: "e349accc8cca63eee46e242241707ce34f59d97d453861cc946fd50f1a9fe842", BlsPublicKey: "121d40505c1b5c18246413f240e3553611deead8c66b0748115dddf23e88d2b965b40e0c93a486b43ec1ad179ca44b98"}, {Index: "31", Address: "one17nacqwrnwgq7pk8eehn7j6jphxt0draqpkztpf", BlsPriKey: "849ccd91efc2f08069aaa14da598625b98da9781d82795eb454645e76e7f3c36", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "copied from sheet"},
{Index: "32", Address: "0x689a35324d6B8DDDfa3bF5E7b26A23E704dD0100", BlsPriKey: "1ca6cc7ccdee0975f420075e6215f98816a45644cae26007f62e39a4bff0e760", BlsPublicKey: "6256c4e511b0133391a3d9601076f552311ca0b85c16a091c8ad86eae49f8e37b63bdbb3bf35ef9c994b4b4eea877818"}, {Index: "32", Address: "one1mk6g87mtgcyy95xp0v87q0srggmusp950gpn3w", BlsPriKey: "0c4935f170ed7485249d2b64cd02d4128b4b582baf8107b208f94c6dc7bc5024", BlsPublicKey: "325c13b66bb05cbd7ec95d78e754cde2afdfef83490253ba96a64b3be73fb862bab57dadd42816462a0aafa48fa08d06", Updated: "copied from sheet"},
{Index: "33", Address: "0x6A6A5FBfA9923EBB76f9E42013e7C4f3CfDC145C", BlsPriKey: "536af6cc234a36482073734262ddf8661a88ab4683d1536bf9018b1b99a1ca71", BlsPublicKey: "2fa4fe498354d94973fed971de72d1f721bf0daedc815973a31afbd6c9616480c6d9c8e5aa07b75110ba4e290ef3c58e"}, {Index: "33", Address: "one1df49l0afjgltkaheussp8e7y708ac9zuyfpfle", BlsPriKey: "6d1075344744fe303f27baf4d4bf05b5d2237c1ee70b461fef4bfa9d8bd98f27", BlsPublicKey: "e1febbaf5af29b651662f1f2ff2af2ef9e3d9ca324c9c8526f3486a148293fd5d4b591b63f1912422a4ea162758eed12", Updated: "was in code and updated from sheet"},
{Index: "34", Address: "one10hzlc82dhc35nz75srutrhqkk7vvvyjnewclt7", BlsPriKey: "aceda23c7d4c6b1b2b3ee68956e372fc71076b1676b9fc3b59f378a2831d7107", BlsPublicKey: "50cffa3cba5b39eabfec57cacc13b30df8336e8b774892b9362f8e7566675a4b8d692eed3068aaba61d9e3707a236d8c"}, {Index: "34", Address: "one10hzlc82dhc35nz75srutrhqkk7vvvyjnewclt7", BlsPriKey: "7d27cd0139e748b6eeb2f66f2225b63ddf9760a7e7c38a8cb61d8420cef76039", BlsPublicKey: "d4dd2fd73bf050cced2b8c92255e0a907abec0b1e1470d558f50a7729e14b6fe46cccfb8d2b696c23b1419d7b49aec85", Updated: "was in code and updated from sheet"},
{Index: "35", Address: "0x6c11b83856804D1eae8823beB697d09569fE87A0", BlsPriKey: "60b72c9e631238352bb9441af0f0e5fad4b206a9ae50c407c07aebad48bd182e", BlsPublicKey: "004082881fa702fc6686e8e773f1a9b900c7e7690ae1b112b3451c383493f1093b2046e473b482e62b3fb142b9a52989"}, {Index: "35", Address: "one1dsgmswzkspx3at5gywltd97sj45lapaqmk0hzw", BlsPriKey: "69a0fae29bb2073ad59182c31690baa7a8a459179858c8c75c206762b77d5031", BlsPublicKey: "934fe59ff2fd6cb296885e35d7e722a8c4da27a65a8b81bc73d82fca822f3a2c35ad6b7b5f70f6992f1f92d5d6bbad8f", Updated: "was in code and updated from sheet"},
{Index: "36", Address: "one1w2m2al52exugww4c2nn0fl2gqx3lfvhsq3x4k3", BlsPriKey: "1d75c858647419a303c193c5548757769c683c3e308b0da06e00a9137bb94d2d", BlsPublicKey: "ede38b2b31137828da86c40e248f5b5721a836ed17d86db1d663f375413d271b1f8bde1da635e999636c520ba517960a"}, {Index: "36", Address: "one1w2m2al52exugww4c2nn0fl2gqx3lfvhsq3x4k3", BlsPriKey: "c317068d813f0c28aeb2dca676cd079176cbc960054161086d592b868ab64b2c", BlsPublicKey: "6558c3beb184401ba26e00cb10d09a01ead04581c86074a596d0c80cc2ef05c9fbfbb6068ea1f556345e6cb39e2cbb8e", Updated: "was in code and updated from sheet"},
{Index: "37", Address: "0x76f8d12F6624f713B2D8894A749ad926F7812350", BlsPriKey: "a1babfcf9487ea8ec9e54aabd804c197b75af986b48e8049329141e71bf7e43d", BlsPublicKey: "a92b18c9467683e80d07e3b08269797eb99f69bc3f1da507a35d2642760af650c0b3b172c9813f2ffcd7e8d9c6d2ed92"}, {Index: "37", Address: "one1zzhwus03x3j3fgtust0v07k7rf583rrp84zdet", BlsPriKey: "27b8df104400b9542a6690f41efdc05cc81973d59378da15d27f6890e1934563", BlsPublicKey: "7f01b62e63b020c1406558153393f346230e7a87d4921bc756bc08e49b88f749b45bb624dbe79e4d95bd83bfbdac6605", Updated: "copied from sheet"},
{Index: "38", Address: "one10z5d98vpm5pvzw32vpma3p70vcdk0ckq0znapk", BlsPriKey: "d5d39dba1ac122d4493834612b0a667a9643c9b4e668928a067f64d809263c2e", BlsPublicKey: "ca19e0364990f1448acb1de99076efadaa9bf14475ad2c70e3657d2e4c50a429d32bf5ef7a98c43d4da31d193a834f8b"}, {Index: "38", Address: "one10z5d98vpm5pvzw32vpma3p70vcdk0ckq0znapk", BlsPriKey: "0c56f4f9ea21f3af7148662f9188e686aecaa91e9d780a0083c77bb3700cb11e", BlsPublicKey: "8fcd36c080db9b9168d5f3e6b6854546544f62fd0b224c79c1e12e3b93674bec513cd5fc1e9748690e0e5d14a9066c86", Updated: "was in code and updated from sheet"},
{Index: "39", Address: "one108uwrdejhf3es7rn6h4cdjqnvnpv75pp7t5ne9", BlsPriKey: "a557632723207ebd0046f42edab745f1e8c47ad7e5fbd3633b6d8ecef8e9f751", BlsPublicKey: "3dcc479ea8198175604e94ca1e5e985538526f0c971d9b360215c06148d6e1d63fac55b771165f2cc0c1541ea49ff605"}, {Index: "39", Address: "one108uwrdejhf3es7rn6h4cdjqnvnpv75pp7t5ne9", BlsPriKey: "5ffe9146398f7e2d45ac7a162fa4e209696d44d54565c3ebc8c3ef6bff680322", BlsPublicKey: "c541fa6d4d97bcae0e502d5dbe64ba9d2b6b28fc8cf498728ab249d9c9efaa5148eb91b0d9827d7effeb36720f0ab813", Updated: "was in code and updated from sheet"},
{Index: "40", Address: "0x7A4306d4D0A4f15A5fA54486cE4e6403E313805A", BlsPriKey: "85ec67510eda7cbfe6d48b2471d3f4a8466ee419e7f098d1447a2064d9feaa3e", BlsPublicKey: "130199723c20f644d9497e00ec3e883bf142af8a7bb8493240ecf16407d5486ffc9500da5f28d65547d7cb835a2d1908"}, {Index: "40", Address: "one1sp687xe0kk93ngp8kaxa2qd8yjm56wjmup8mf5", BlsPriKey: "041a40e16c3ddd45c0277237f19cab5d4d7798f55be1afb6c71fb74ab2abc66c", BlsPublicKey: "c48e26ce1e845cfbb032fc08b91cbcb7caa8cfae8f28db54e71271cd53423a37eed40e75884c21cf1b47636fdf77058b", Updated: "copied from sheet"},
{Index: "41", Address: "0x7ACDCB2BAcA2911BdcE98e308515A289ac60b7d2", BlsPriKey: "a417d5eb94a995ab5458e509bb9015668c7c46fcf903ab896ad44dcbfd523031", BlsPublicKey: "c76c6795eafecd027270d98c48bebedda5b78e8468781922b9d1013af5a1bf812bc716d98e477e1322bfc3582909fa08"}, {Index: "41", Address: "one1ctd33zz6zh9p5nh8w6qzeldq5agpn5gxmq2lsq", BlsPriKey: "d61d338a1339330b7601916e4b0dc738015098017fc32e769a303755d25ea431", BlsPublicKey: "a0ab990e83bb3fa72158b776b7146a7c603d878c4b24b426a70b2cc60d81fb3d6f59b1221043804893a474e1cedc578e", Updated: "copied from sheet"},
{Index: "42", Address: "one10ap00fxkdupc0tnh5gvaqapw3fcxyvw2d22tlx", BlsPriKey: "bd197680b9a4d8e38cd5b393be386736dad334fde8761c6ced18f8901bc14051", BlsPublicKey: "4f61d122076909202b7c174d5a0850eb17dfabec478de1a8c212e204b85ba663751b7affd02fab0598701970e1213196"}, {Index: "42", Address: "one10ap00fxkdupc0tnh5gvaqapw3fcxyvw2d22tlx", BlsPriKey: "04471a89250fd9bb85682cadcd5738a1695c3b20a4ee27a768f90cd13ff9d207", BlsPublicKey: "bfa025fd7799315e528be8a985d1ab4a90506fca94db7e1f88d29d0f8e8221af742a0f8e9f7f9fbe71c1beca2a6c9690", Updated: "was in code and updated from sheet"},
{Index: "43", Address: "one1zjjul68lhv8hef7angwvakmc37evv8gppraft0", BlsPriKey: "f7cc5bf3fde6f20cc9462a5da9332bc2a7d276cc330baf371a37a72477f8fd37", BlsPublicKey: "8da3511d56910bbe36fb16829eb4a601da7a3f63488b74b0f5ac548b91f43a50c18413288797b9e1f4a99ebe9c7c4a17"}, {Index: "43", Address: "one1sq34zq9xnxans2cj5hd43qvfhcjwtxlkc3u2a2", BlsPriKey: "7e5bffebf251c46c8b5183ea44cc0a72b3787be0b66cddcef0d8e915503f9d25", BlsPublicKey: "c8e219cbe0a03c6d97365584e8c239eb55605e61b5f3a4810f75e655b08d6b9dc7816af45e21c72021824011d4d67809", Updated: "copied from sheet"},
{Index: "44", Address: "one1sgcpjc405ueglhp5udsskjxcn8crrc2lmuf35c", BlsPriKey: "d811e24a6a46dece952d04cfc6ea6a3ef736cca8ca8c5125c07cf5ae626ff364", BlsPublicKey: "c06236fbfb1ace3a351ba73e40ecba75732fd1aaff39a88f1a8cb89c64c334dbc94b808ba1742e16f6b8791add65bb15"}, {Index: "44", Address: "one1sgcpjc405ueglhp5udsskjxcn8crrc2lmuf35c", BlsPriKey: "4781312de913e9320bd558af66e67ae47864752d0c1fe3a0e1b65915fd63244a", BlsPublicKey: "dc9e4e6c9e4782012ccf628e3d3e7c1763ba2f78de99b98b89fac63b1f4375e288d5e155e9ee64fe126f78ce0088db10", Updated: "was in code and updated from sheet"},
{Index: "45", Address: "one10746sav20n8h4gm3sevj3vfydtpv6vpksv2065", BlsPriKey: "d71db7ef78e1d2e5b89ab5834f8cad74393c96554cb388006b5c0063fbc2184c", BlsPublicKey: "924eba31d0189755b4fd48a70f8c6b058e4372385ccfbc9a7003103097af3d54adf10ab1f531d7de67aea97f38143b0f"}, {Index: "45", Address: "one1n9ecmpqfnf4aztcq245nqqmnjn7pxamwmmuvg3", BlsPriKey: "51d0b5b2324b69601ae4b4bdabc3130c7afdf5219ec867654f2d87675c8ae970", BlsPublicKey: "d468f29d36b05b647412d8fd975e0625ca959d5f04ad9a91513e153a2a249158df2b421d29730287848b6a7a674b3492", Updated: "copied from sheet"},
{Index: "46", Address: "one1s7s40ku4ms63066h34xwmm5j5k4jwk74gml5nx", BlsPriKey: "917929a073714aa2a9bf5776b14bee7d116967241d1c01711ea3c2f62d830f41", BlsPublicKey: "3fe28f0a78267fffda921cd5ce91ca6aacac2382285c37b87028c231e8400f285454d18df5858a556f45dc76d2363884"}, {Index: "46", Address: "one1s7s40ku4ms63066h34xwmm5j5k4jwk74gml5nx", BlsPriKey: "65ff7b77d6b7e2cedaa9f787a94c4ee4c776b0c8f7e4ac8460659541c70b9d6b", BlsPublicKey: "9b58fac96afe10ad8832c1752ef35c7169826aeb05505e25002320e63e6200a9c9bc10233a9a258797084122d4b2a411", Updated: "was in code and updated from sheet"},
{Index: "47", Address: "0x880D5c6aD4117D26126543Af48f2f9bCDd4DaA0A", BlsPriKey: "aa6599d626b55a3e0f818ee83d728003030f8214181092717f03681b0afcf355", BlsPublicKey: "e515efe19e9ce131619bd1230533c5352cc91e64bf4f61a23a3cc8a0073110c2c9d360b24a5646783d2cf6c3c4e29b02"}, {Index: "47", Address: "one1s3typcymaa5dgvfu68jw0hufl7vyu0hd3hscku", BlsPriKey: "7ee0890d586752d8883f28e6602c29a660b8f189524dc2f7120da9a1d57ffd38", BlsPublicKey: "d8bcb7ef85977e33f429374b68ac7e8b1d9296b82a074aec212ba570cfa0a5489df9c020f941039ad48497adc7833a96", Updated: "copied from sheet"},
{Index: "48", Address: "one1rfaajrvn5zdfxydf5wkvrwsyylza6205xap9x0", BlsPriKey: "ccf9344200b12a4ed9c6c4b37ce854c0cbad4cbfffeed18dfe7c46efaf2a300f", BlsPublicKey: "dc7a9515062b240545755bf53134631c7eda44606f2fd23be0da6f286ef3d151f0a90f170b64bb4b13891d841093e619"}, {Index: "48", Address: "one1qcecvkv9w77rfz75t0s7x8xpgtw0nwve2vk2sv", BlsPriKey: "a60338bcbc1b33493683435b8133b0f17d9d8303a7b00b6507bb097fadb1c82c", BlsPublicKey: "d12e2b82d430ff6ce19651363bc29e438169ed1cd481adccdc0a82b74e789e18f330b7be9c1e399cce30506ec726c80f", Updated: "copied from sheet"},
{Index: "49", Address: "one13hrrej58t6kn3k24fwuhzudy7x9tayh8p73cq9", BlsPriKey: "a49c1af4dcc1b9845c46f97304eda460e1f76f7a602c471f8471cda544de474e", BlsPublicKey: "7703c8cf4e9b9a24d42e62ba6e2d71b3c51aee0d54f1d75991b614f4f1933d3b518ddd7ee9eb252c288460120052dc86"}, {Index: "49", Address: "one13hrrej58t6kn3k24fwuhzudy7x9tayh8p73cq9", BlsPriKey: "694db80220180cbb64614fc6545ba2ca9ba70b75e89bdcd99b1f1cbc52c5cf4d", BlsPublicKey: "23ab4b6415a53e3ac398b53e9df5376f28c024e3d300fa9a6ed8c3c867929c43e81f978f8ba02bacd5f956dc2d3a6399", Updated: "was in code and updated from sheet"},
{Index: "50", Address: "0x93570Dcb1Bf1a0bD1d476a542309754a6dbCE632", BlsPriKey: "630f6bcd3d7efa1e634565c6702d9cbceb7de22ea6bd1aab8189fec8347ad22b", BlsPublicKey: "7c7cb5b5617d33c501615b4645b6d268f0132c67f1c543aa74a89d7d283534a7f5717efe3037df0f4e3a54162e947609"}, {Index: "50", Address: "one12vyznqd6lz6wwr9gkvd6q5zy9sswx792dh2eyv", BlsPriKey: "8767c541772043e0b4da32500f8e0443db2fb41c794411d8b3b4e5020d885504", BlsPublicKey: "90afed6000f27a5c47f04bf072efc3a7e75a6f75993c91a56a29d3c367f0952d97620fecd06c879c13d1068d62128506", Updated: "copied from sheet"},
{Index: "51", Address: "one1srnk0ekhuljsvsqykg6f9s067xfg6gaytle3rn", BlsPriKey: "ef2a01ab5838a13933d9ec45537c0eb548dcf238ce678eb27419ba72cbcce025", BlsPublicKey: "f6ab41ef94721c0b7c941382dfe0000a05d8fb86677ad6cbd689fac5fa79478a6e3772d3cd912aa75ea5f55b7e769f89"}, {Index: "51", Address: "one1fdtcrkpkhm2ppnu05zmddgqvledqh7g6r2tgdy", BlsPriKey: "603e23f327d4afc4d347939c0bcfd56896f9850ceb38ff33906c0bd6bb361837", BlsPublicKey: "493fb42bd1fa4c0e01e88002d2a0a1f443cbc9e7ea17536e8a83ae5c911530b2534d00b1d681e253318be7e1fab1f193", Updated: "copied from sheet"},
{Index: "52", Address: "0x97b834277538e4517f43f9E11fa0BbebaD7c0d3e", BlsPriKey: "1a6a7f82aefcd737cf44016d8ba20bde1bd96f1392f6bd798f2cd1d097be911c", BlsPublicKey: "f85680ae5b835445f0f42b65ba4c242d278e968a93769e611a98d3cf72d8ead561356870dea87a54b8ea48fce16a6800"}, {Index: "52", Address: "one1j7urgfm48rj9zl6rl8s3lg9mawkhcrf78mqdsz", BlsPriKey: "62b9c51b728314acec770c067d1aa47e7635ecbb1f2b90e3be2c34fdbe03fc3e", BlsPublicKey: "0a8599d805dfdf109de0fb849e73c12d4738dbe5de3f01093626947207f1611756382e8e743dae22b3b4e5fe67ce6d16", Updated: "was in code and updated from sheet"},
{Index: "53", Address: "0xB88AB7A6678c87aeBE7b753459258012eb2Cc76c", BlsPriKey: "1ba26ee04ecd1f56487daff9b719de07cef181f534c892df2c6a7e0cbca60822", BlsPublicKey: "004d32e0d2694a53e7780900b63ae60f281e92e6128fb7ffaa2193e4e0be5b662319796e0557ae94a64a143e97853793"}, {Index: "53", Address: "one1s4rypls26kmzg03dxkklmpwhmv8u4nlh6vqkdv", BlsPriKey: "a4eb5c77e47a86d78420b526ff4ae973205d47f954adf8fc667b4c141ef3da5f", BlsPublicKey: "0d42e7e1c9ef4c1425bbc767b172154ea3e3d630b23b7a92d5cbceeaed3652e9c3ff2779bdce5bb85f1d328458b80117", Updated: "copied from sheet"},
{Index: "54", Address: "0xA28e6f8D23cc3Fe77D531c7D60bd73F8fD71C5c7", BlsPriKey: "363bb667ea68487660260888eb574be7ba602eab22d2eb18c764077ae7cca529", BlsPublicKey: "7e99c7591106405631be00ee8ac8410eb252f174d21a8f46dba3da93a696540559587b65ce8e1a0c150f4f20f9b93e99"}, {Index: "54", Address: "one1uhqaf9jgeczmuxs7ydzfeevwnt63ftps752cnr", BlsPriKey: "ab924789a57655b1df82a80138e3ff81c82a37b561bd17d5ba3f8e1df9cfe624", BlsPublicKey: "9c99088bf4e3d367183036041a32e534c2e045d9af2d4d9591252a74ab38b878d89f2863a1f5934501a8e9cb82b08b07", Updated: "copied from sheet"},
{Index: "55", Address: "0xA41F4dDd1b11A6107f1973037D070869495e71E4", BlsPriKey: "b6b563928e8fbb96a92f06797ab5cdcd12b859cdc0f57091cd4f1110aa36cd0b", BlsPublicKey: "f0c7d6ec692cba4c4ebb7fa4c54981313bcd2bda8352217cecd06371ceca1a1a353842ef7f5e41b433697fcb7046c617"}, {Index: "55", Address: "one1khuc8sclm8lr09e0r64kf3jjt684leggzp22h4", BlsPriKey: "ae9495935096d4a403e056d46732b80cb8053ea5e3edab5b947f19bc2058f35a", BlsPublicKey: "3af05ef78a3e2b4ef4f2726284705300b88066f350506027ed853dd96a270671b46cd4b0ec675f8c9ebcacac7f99b984", Updated: "copied from sheet"},
{Index: "56", Address: "one1tg3v0mq408qdsamq7nywcvhmufx5pcwuu0daqq", BlsPriKey: "08420fd6c409523527f47fed73877b7eac2be8009709da983a8a16636b6e3438", BlsPublicKey: "aecc5215575d94f035455255427be3cebbe5bf601e4a7c0cc6c8b7b62fb806aea077f539b3014cc6a5ec3f8fb80c3f91"}, {Index: "56", Address: "one1ee39d33k3ns8wpjae6kdm46620m0v2djhacas0", BlsPriKey: "6055a4efb40f25b0e800ecf79b99e364db2d92594530d944b29fd9e718f8b751", BlsPublicKey: "514b80600fd2b70fa83dd0a49b526289acee59d95ebcc50e87e05acb690821da064e43c9664683b519352861852de401", Updated: "copied from sheet"},
{Index: "57", Address: "one16jvl43d059a4wpderqu82wlm7t3qzw8yta3wgn", BlsPriKey: "20617e9a2fc71c05dffe53f75fbc9b98bb9c0e121926218be73946fc63e23763", BlsPublicKey: "26b5fedda9241e95906205a0a9b584610fbb1c243aa845db9027b7aecaf8c371786ab020f2f89739c9a940bc02bada16"}, {Index: "57", Address: "one16jvl43d059a4wpderqu82wlm7t3qzw8yta3wgn", BlsPriKey: "5363d581399692d5eacde5c42bd5c4d177c02451e49ad0baa7535377013e665c", BlsPublicKey: "f7af1b02f35cdfb3ef2ac7cdccb87cf20f5411922170e4e191d57d6d1f52901a7c6e363d266a1c86bb1aef651bd1ae96", Updated: "was in code and updated from sheet"},
{Index: "58", Address: "0xfF86Ff1FF457c3eBc18D71ffA30cfedd0860559c", BlsPriKey: "6200ef5ff6f5b8c456bf0b32ed710457c6b5b55c8902b4860134aaaffcff5962", BlsPublicKey: "04bdf20e8ca05a6ede7b5fa8f5ad5a664bd2e927decc43fa8f59f47b953a13842b01cb818426b190e1eb4d7fc6a76486"}, {Index: "58", Address: "one1xhwspfzgv3vh5fp9hxwngv8tvdj2qr338lmavw", BlsPriKey: "00bf369ebee045f0b6042d7a704d75aae2dd15b516e66a0d576ce7b32dceb70e", BlsPublicKey: "014d802636d36a50a687512b4f81f4d93324518c8099884b90e5467fa3d7f7fd52ed2e65892db70edf6df4a30530a78e", Updated: "copied from sheet"},
{Index: "59", Address: "one1ksqcladc3r5s90v494h9tfwdhkx88tq6j549f6", BlsPriKey: "7d224cdacbcf76cacbf4eaaeb660cb2c677acff80fdab6afa802fc735d267d2a", BlsPublicKey: "d5205e769f7fe412e4c9701f4bb02e094f3e222010cc27a4346cf063d94c6a05b1e291177088461e90cc12c848c3cd8e"}, {Index: "59", Address: "one1ksqcladc3r5s90v494h9tfwdhkx88tq6j549f6", BlsPriKey: "7daa79d0aa2f62343c8a4bab592bf444ea141ee9ccc8f9515434bdfce72d3f24", BlsPublicKey: "286c00f71145c770f2c791492b3f26f7150ff2362780755530539c02c9115de76503ad367ab981065d3c7aa658140b18", Updated: "was in code and updated from sheet"},
{Index: "60", Address: "0xB68751A436f287CE3DA347277259af5c7bA84e38", BlsPriKey: "ec9f87381837363000db4ec207745beaa6e50b30ae9269146888a5c2f2520d08", BlsPublicKey: "524443b2929d75bd24d5e41a94f94d38ed22c892bfeca4468d25d37c478b157bdfdd01d94a77dbb187e99624d4f78803"}, {Index: "60", Address: "one1780wg58e86rs38we6ze2ts930s0qmmu40vmzya", BlsPriKey: "ecbf09caf2c9dcc4688f98d43a198a16da25162b249f31995a9ae3b4fa17b82c", BlsPublicKey: "109c9d8364b1634802b53be754a5faea7c6f5655f0990de979038462ada5cbef325c36032e6673d30c3349936b0bce18", Updated: "copied from sheet"},
{Index: "61", Address: "0xEd677E021df3542998e407970E1127d334Be0285", BlsPriKey: "ed2f6756ed0d065e8fbe61ace2536ee98b28ea7c2aed1b7bad9ce33fab675b2a", BlsPublicKey: "b151c927871bccc5ea6e102946a70900a39ec1e993c92145068662010f26995e88aecd22aeed79d289b260117f7fad19"}, {Index: "61", Address: "one1a4nhuqsa7d2znx8yq7tsuyf86v6tuq597y925l", BlsPriKey: "b55ece450a0ade36f98ca73906cecc543ddf96858fa6577aa86b3967889f6673", BlsPublicKey: "7f24f0c9af2239090e6ae593d665589651f4d8c4f5bf8ad40537ea8d3e912da82588ea3b505991b2aa96057015d1458d", Updated: "was in code and updated from sheet"},
{Index: "62", Address: "0xB99Ad8B391eDD1F15c51f773F4bc23Bba7dF45F3", BlsPriKey: "187a5e4bbd28c60ba251885ac351b66bdba9d258ec9dc10183fd319d9f9a210b", BlsPublicKey: "082c07d9446bcc1e86d40a5bc859f3a25bbc3bf983625e889982b54367b206735d0cca074e9075856787d64ab18e4f17"}, {Index: "62", Address: "one1r9hjnk6zmnkageyvvsypcw2p675x7qrurjeaan", BlsPriKey: "57b9b2a48fe3d24e80d9e616a45a53d517e222fb90559bd0fe470bce027b3b29", BlsPublicKey: "3f74037361a915ad7718d96e225e4803c9b8a31bc287f246d6eb84328c5bb63ccf32975644d6a74b3820d3dc7811e592", Updated: "copied from sheet"},
{Index: "63", Address: "one1c0aau6shrtxqgenpf5ymtrspxpvw0sxj0c7hrq", BlsPriKey: "4c703161308485e6c88410ca6250faae4be99e4d1dc58142807a1fe8e1cd286d", BlsPublicKey: "0418489ea9e74b8219c240b509551fa9bb273b87f967105f72a1628c2f08a013fd8bf14d7b7886953d1080e8e37af207"}, {Index: "63", Address: "one1c0aau6shrtxqgenpf5ymtrspxpvw0sxj0c7hrq", BlsPriKey: "c6582e9c3477926891fe76ccf6eecc024c5249eafccb6c63702c5c8884e6ae20", BlsPublicKey: "ec2fa7a80bb5643958765cc4285eafced0c7be0b7b5543454554f764e187d63ff7952be490428974b8c81cc90db44899", Updated: "was in code and updated from sheet"},
{Index: "64", Address: "0xC6b6a71d6f0C5b98E25FCf14b5378c807B0d475a", BlsPriKey: "e0d5153033ef7636eef27ec2506afc370213a7da628b2d84e44d5e2c4ceb5d3f", BlsPublicKey: "90d8353a2032070d4fcdf5adcfdfbea876ad75848ca73644c84e2b60870f33371b91e4fc13f3e481859839e6667a1103"}, {Index: "64", Address: "one1c6m2w8t0p3de3cjleu2t2duvspas6366jtf8da", BlsPriKey: "21b550fbae41803181de9625f5b5e5bab1ce8b20f2a2bb09f712ba4718346516", BlsPublicKey: "47ab7b7cbbc5b95ddab000c5d2643aaf9f916d776bd4adb05e509add43d54579f69e3e5898df5dd15a4332112c1b3d87", Updated: "was in code and updated from sheet"},
{Index: "65", Address: "0xeaD1fAa7E5Fdb6136057d4BfCa1f05D220D1441f", BlsPriKey: "a2dd773288472148761292b08d3460f8ac1ee5bf38b5953d6eba957be73e776e", BlsPublicKey: "65638a6743568b6cf124432146f42110782b08e5a8d47afb90ac5a91d692b2434bb6fb125aac58f9f56bf7c0de23e400"}, {Index: "65", Address: "one1kq0xzzzlrpkzslwfesrgmp5e7umuxl3m3dgk27", BlsPriKey: "a04f434680a86af6bda04f3ddf5ed7d420510890e3966a1f53a6ab7e7286a92c", BlsPublicKey: "7df3e402538cd967ac002d9140167fe2c70f591b487235e5b1929ef128cf93174545d663b1d73923acefc6c629368484", Updated: "copied from sheet"},
{Index: "66", Address: "one16ru662mq0yh6lup030g09kwwy7g8yfcxc5fcfp", BlsPriKey: "2f9b236c721e0eba0e8177ef935129bfa21c65e626c2587f46c4d93a33940c3a", BlsPublicKey: "3fde405c8e8ac960c8775f4c60014fe8614fcc91cc76282c6cf3b29074eb824d5409f4314deafd65a4570695487ab410"}, {Index: "66", Address: "one16ru662mq0yh6lup030g09kwwy7g8yfcxc5fcfp", BlsPriKey: "33b7d152eb29324e05d2d2a8f6822901310455fb0a1a47e226e8d09b4a0d5733", BlsPublicKey: "d35d26c704c0094abf6c1b19e1d6ea6021eb20bf347e9c20ff5a710bde93e9d41977ba6eb5191809758cceff59132508", Updated: "was in code and updated from sheet"},
{Index: "67", Address: "one16295hjtqyr0z22swaqthv7mvmvn2gltnj5gera", BlsPriKey: "51e302006744d8cf4e182593cdd77e01999c60ff87bc30ff6235b8f456ad9834", BlsPublicKey: "9312cd3e5805a4f7a505ca6ae95ce726a8878aec9f0e99db7eed11fb30aa212285c04b009f738a92c42be77ec70c8d82"}, {Index: "67", Address: "one16295hjtqyr0z22swaqthv7mvmvn2gltnj5gera", BlsPriKey: "1692432c25673c8f5026b0e366142bd4130b9c2ef86647280576fd6d51eaad62", BlsPublicKey: "fca5bb8c78055a4927bb3b8e60917e87dffd00d5f4a818111113c6ddff4e4af69f0d878a49c8f39c0842c15b40d0d603", Updated: "was in code and updated from sheet"},
{Index: "68", Address: "one16vgft0s46jctzejha6mjurxgrcjw4sgpv4e4hn", BlsPriKey: "6139c6b5f11b12d0438cbfa0f4ef2fa65b9819190941913b70d7b5bcc829ec2c", BlsPublicKey: "be269ffc1b44138041ccade0f03122cdcb0c8a1d998bd2f5fd8c5fd4c550b0a405dd486e437758bcc688965c2eb71d93"}, {Index: "68", Address: "one16m5r7awa4y2z2cyage4cns4uejxx8rn0gw77ug", BlsPriKey: "5ad6f65e17f463fabb0d30d16956373e017a09c374ad5a180d9c2f6f9b9eee58", BlsPublicKey: "056f7e81e119f343ff72223955f7c007ffeff58dbb6e67bdb99d8c187068eda288b7dfec63dd7dae5546d9da3b89af84", Updated: "copied from sheet"},
{Index: "69", Address: "0x35D29200aFC9A4cDC05166096059a042078CB53e", BlsPriKey: "7c35fcdf02e86a32018c51661d1e72d01fd4158a3f8c48205f93ed6bab03e83e", BlsPublicKey: "62ad1ec48106e0de5cd62db8e5ce11d3df1ee6b7cb5819c5a991d1d3ed1d0fc5814bf34eb25cc6ac3aeaf47b942a9687"}, {Index: "69", Address: "one1ha85rtgc4u96v4v9nwam5qhchswx8d579dw0sl", BlsPriKey: "633b087412f23e3ae86590f790c20da7ca481528b9a5266629a84ed71ec9101f", BlsPublicKey: "5655e508219092659e9440a642f58f3476a09539b552dd7d5d5fa4f1fbae006347ad7a3ff3ba59d3996a724822ca0e87", Updated: "copied from sheet"},
{Index: "70", Address: "0xe4a69826534aD3f6ec6E432474B0380E7F9a9C3d", BlsPriKey: "70931311c44fe590478333abc4cf9118c394d6a7556e355e29778e68e9a18465", BlsPublicKey: "ca82d99b2648613c4fb86fff394110e6f5d3739c309f5f1ced9a87edeb73ed261eb35bbc481772c0d4709aa69811ac00"}, {Index: "70", Address: "one1mr3mt2ra8mwpr55uv3ymv0lmdy2s0w4m5nt0jh", BlsPriKey: "882457d412de8260589d1a64ee4163fa9d47b40905dd03b7004d705cd087be58", BlsPublicKey: "9bffcf238da1966163905e83b8b9b4193fc0a0408091347f3618d652f67ce5d40991381f96e85782ad94c705177c3082", Updated: "copied from sheet"},
{Index: "71", Address: "one1u24h3m8ny5yyfpv40vjen4fme72ye09gn5mr9q", BlsPriKey: "869278ffd4dc0505ef2b4c15bc359545369c81e19295d03fe4b872240b7a145a", BlsPublicKey: "7af60b98066f2ed7e1ced9b91b82b9b82423cd185fc2db6e58e09c8ec85e1efc1fd6f2b7f3ce67a2f62e0f0e272e7488"}, {Index: "71", Address: "one1u24h3m8ny5yyfpv40vjen4fme72ye09gn5mr9q", BlsPriKey: "e1f32d06cf1d98689713adf15e0bbb3f74b9db423ffd0e805c2bdd3787579507", BlsPublicKey: "emptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptyemptye", Updated: "was in code and updated from sheet"},
{Index: "72", Address: "one1a37yjkrxdzwkkl3ntkqsv305grcklpksxkwsrq", BlsPriKey: "f124164641b0d2497e2e37101b8aa298c2def5d9020050c6b3b12cf0caec4706", BlsPublicKey: "9418e9525d68ff8a24d983358ffd051fc08abd39894ee76c5689ec9fa86fb31fee9c80f3198dcb2fb77c947e3be83991"}, {Index: "72", Address: "one1a37yjkrxdzwkkl3ntkqsv305grcklpksxkwsrq", BlsPriKey: "7589d11122b7216c6d43a5775d0e831e1a6326199059fa74c1de739826df8013", BlsPublicKey: "afe3e92e45d8e49b8b90957cd8cd6f312d0588d823d761ea2ef0248c9baebdcede4565054a56483edca065c0e72b5d16", Updated: "was in code and updated from sheet"},
{Index: "73", Address: "0xcb0A6c1914d2AD10855cC8cD70B040b7Dc6573a8", BlsPriKey: "dd03e6f10bcd8c6673474d20080c4f80ec8b39faf147566eff86e4f0bea9e705", BlsPublicKey: "1e3631843521b947cfb756df0ecbf74b2e9445f0a7ca30fe2b3fc176e519ef8ba50fd4010343de6b8de17ac9b35f3382"}, {Index: "73", Address: "one1528xlrfresl7wl2nr37kp0tnlr7hr3w8u5y4dp", BlsPriKey: "4b0f6878f44d2d21eb77d42206cc63da035e01d97b2108a0afc24b7340ac9122", BlsPublicKey: "91058b91d14936926f279a407dcb679f8756a51b3ca68cfed10c2c67aad13d1dc4bce417cd8a6553d7343bc0aed5ef02", Updated: "harmony"},
{Index: "74", Address: "0xf10f63f5Bd46c58d2e9530E7F8cb6b4336D05d4E", BlsPriKey: "d2ae1195433f32723f4b0989629b3fa26a4263296fad6b874660a10fac32f462", BlsPublicKey: "56fb1f429138f192fab6aef6fefdf25dbd04ef94f274ab688c09284b93f6181f4b515b18716074c3fb54970f43add194"}, {Index: "74", Address: "one17y8k8adagmzc6t54xrnl3jmtgvmdqh2wzexn3x", BlsPriKey: "78d4ff9d2c003615ac143e7719b9043c2575eca6819ea334e3cac16a05253545", BlsPublicKey: "31c2be76384a46b596943d5071300d18f1e3ca3cc4418557cbe7645f141d163a448e750f876ace5663ac5cc8dca2e78e", Updated: "was in code and updated from sheet"},
{Index: "75", Address: "0xff1bE0eAC9B6053CD656947F0CcE7d277FF720Ec", BlsPriKey: "60e2078a527b2c6de83e4145128b59d2a7d639a73e1b43ee6f2f92306e33f72e", BlsPublicKey: "fdc41bc82930e7dc88d26f2767551098c622fd1f3321aef15b693ce64c9cf1f757b264a53d41fd37774f63f2fb827e97"}, {Index: "75", Address: "one1284fqe06amt67j6cwrj6c2yrcjudeq0uygjyq3", BlsPriKey: "2a54d6f2dd36d81cbd34af9f0448ed4a60f9f1743b81f20559a46e658551d321", BlsPublicKey: "2eb142677d24082e1435ac54dee102c9fc9d897c2f87ad9f99a88cac93445be8cc295c6b2ac34c196cd9b6f1b376d711", Updated: "harmony"},
{Index: "76", Address: "0xa3B34f4E21C6c44A603E3c53abbF8b10C7BdaF59", BlsPriKey: "78cbefbaac0f578c0f3ad12e3a6d015dd29b58e890bdc7237353bf65dd6d4645", BlsPublicKey: "b68e7f073d751d1758c5c05440f6dfa2ce662848a4b3384753596bf31de849208fb12bc63821a58ef18a979a5b09400e"}, {Index: "76", Address: "one149aw0kne2qwyxkxhz9v0msgf00lndvvdjne4rq", BlsPriKey: "6f9521c771f6d8eba15e5a611c181d80617590ae6249a159aa664d44b043220c", BlsPublicKey: "00508bf582665b3c75442231397f061ac3b9fedc5edc3343a465d9153ea7eca5ed97c33c097ac7a75533a420149dc492", Updated: "harmony"},
{Index: "77", Address: "one1lhyk86r4a2v7gd8yhq2m0k9l2pk64y3z75zx8r", BlsPriKey: "c6f7bba48d3d846204970166be886c52d6ad13ab387121635bc9a0bfe485f502", BlsPublicKey: "b51eb335f9d0b56aaab38fbd2b9858c453f17e98bc088c7b8ead8216265e71d8cc84b214d7cfc0c88ddeb66dc74d5305"}, {Index: "77", Address: "one1lhyk86r4a2v7gd8yhq2m0k9l2pk64y3z75zx8r", BlsPriKey: "d1378a5060854c0fecafd6afc634485e94d72763a5240af6da0f8722c703ba5c", BlsPublicKey: "6bf1696e1fb4c52710a42ced76e0deb458a92d1539efc4632f88f51aa882d9685ea154d126fdaa375add29a90ebc4c87", Updated: "was in code and updated from sheet"},
{Index: "78", Address: "0xa61CA9f1EB26787EEd89dAEE4A326C4e1cb5eCdB", BlsPriKey: "79f012d0ee2a0d2c99d137ff28a5976f88de6a57bb846345ed776e83f3a94916", BlsPublicKey: "58168d3c6c757f598d5085637ff8179cd9f551379b956006325eee345faccf9d087b44825144067b9ee1fd0bf35e3c80"}, {Index: "78", Address: "one1flv4r3udp08az7axdcz9me50kr2r4z65c8s39m", BlsPriKey: "27e8e932adaf0d464767a27f8e3cd18ca0bd144fac435a254ff598c2ee0e0870", BlsPublicKey: "306a3077bc5dc0914a1a08451e6d68072e5ac25cb9be3f4a272f9870614d36f5e96a02e6e571248abb2f174a144f3989", Updated: "harmony"},
{Index: "79", Address: "one15u2v6f56pj3rzvwge4dwl3ylg5zh3395nzj57y", BlsPriKey: "082f550873e394bafea3b80b1982ef21479a3d0ec8ff71a2b9b9b1bfe0cf9b3f", BlsPublicKey: "12ee8d7069c8361e26f223ae8fc074235883da4218973b1f477934fc6d021a0631f89b61a6c97707b18b324fc58a2697"}, {Index: "79", Address: "one15u2v6f56pj3rzvwge4dwl3ylg5zh3395nzj57y", BlsPriKey: "69f67cb5cbb540362d70f1304df641bd66d120c02f8d74b66a0b148f8d16cf1d", BlsPublicKey: "43b6dd212b5ec9aa1c8055653813f7d0edbeb4ac8e1b679246efcfd709965df0ab6537c791423ec14a5f05a47cbd110d", Updated: "was in code and updated from sheet"},
{Index: "80", Address: "one1kyyt7j29h4uhtnuhfar5wmngntx4gterrkd8q9", BlsPriKey: "6debedc1f96458b0e7985184b8d3f7537d0a12c16c38ca2c87f9aa1c00036b22", BlsPublicKey: "9fd3603b86075ea959e7a4ed426e36624ae08ba725fe0a937b656331eb872e9e5b39add470e6f9f92834439fc1939f80"}, {Index: "80", Address: "one1kyyt7j29h4uhtnuhfar5wmngntx4gterrkd8q9", BlsPriKey: "f3f2f59ff197adfcc865b89346280c23078f85181de9af836146a4089945574c", BlsPublicKey: "f400d1caa1f40a14d870640c50d895205014f5b54c3aa9661579b937ea5bcc2f159b9bbb8075b516628f545af822180f", Updated: "was in code and updated from sheet"},
{Index: "81", Address: "0xdA1DF648bC047546326D05dF370ec0ee3D84642A", BlsPriKey: "a452ecc8a6fc6b1064a0b548cd015c2041c565f10608cba458e8656cd9dc5f41", BlsPublicKey: "acdf63ca04b0b3574ee0247e6d0faac0f812a88a4e46a30af1bd30bf7a620f78471cc8b248d13a97da9f497f12ae5c81"}, {Index: "81", Address: "one1mgwlvj9uq365vvndqh0nwrkqac7cgep2pcn6zl", BlsPriKey: "ff9d4e39dbaacfa2b8aacc9819ab369e99b78758c890f44b09511449d7f15e58", BlsPublicKey: "ca5b587ecbc68c1f9af60dc6452f98705073029c27422a37898dacc3451594dcd2da7b75d62a387e3520240ae46e130e", Updated: "was in code and updated from sheet"},
{Index: "82", Address: "one1c4w9danpa5v9zqurnl07lkqdcwyn3yfm86anqu", BlsPriKey: "ffb217a1d17290a00ba7f15a1baa9f3350cf75062e2cebf2bef524db4aacc115", BlsPublicKey: "318f11529ef85120f3c25ae116082e369020e98fdb98f98cbc006fe8904d6e1aebe288a5f30eab6de9cde4d3dcc23e19"}, {Index: "82", Address: "one1c4w9danpa5v9zqurnl07lkqdcwyn3yfm86anqu", BlsPriKey: "c65c08f7d6aba9dc11a4bf2ea16552cb55890d4435f6eeb9950da25f37223f4f", BlsPublicKey: "817d92d1141cf3dee3dd9b522752f4e515fa3d487dd4627951ba3e47a2a2704d1499912b1783cd544cfcdef3abd41b13", Updated: "was in code and updated from sheet"},
{Index: "83", Address: "one1kss4a906z654ujdswn4r7uwq5pqd8m3mvar9ng", BlsPriKey: "8f2208dfa1bd8ab0565458854eefc8081532b75858141bd5e59ed1a74879e141", BlsPublicKey: "673cc8c86ec9e478138a10da806a15e8656ccab8933e8d26ffb5540aeaa88d8e2de7292ef25b6889333331b8161bf983"}, {Index: "83", Address: "one1kss4a906z654ujdswn4r7uwq5pqd8m3mvar9ng", BlsPriKey: "f35d6cff226839b0fcec20a2dbb73f5be3a438476400c3d6a375b3c01859ca3b", BlsPublicKey: "1ec7cce211181f0f942b5ef76c921b88600614dafd42ca06cb1a7b74f69e56f2e6eb9376aafa52519abce095b761068b", Updated: "was in code and updated from sheet"},
{Index: "84", Address: "0x0C787285e1accdD9520dC19f053d14E17B134b18", BlsPriKey: "885a052f3199c74155032e331e689107b1a6575058e28323b17052ae6995a53a", BlsPublicKey: "099f43ac095f31fb1429332fb698b763b1c4f383fbe2d7e5ce88fa13689baf82cfda7c60dadf47dc585f9777727f5092"}, {Index: "84", Address: "one1l7m0e50v0fus6e4wp29fprppj9dyxekhr9qaak", BlsPriKey: "5c44b45f890d8f7e0dfaad51ac48e2c1f887c95636be252413d9a62669559a33", BlsPublicKey: "6fa5da80c6d7c6e22bb98a590b5c380694e2128ee2a5b11379b0f648395fd0af70e8edf834de7523b4388affa329c68c", Updated: "harmony"},
{Index: "85", Address: "0xfC9802AECC486878885F3D36895e209325c4cF8e", BlsPriKey: "6f4de7047da5349a6eb78dd27342ef70c7a20dcfc5a6abb6682cb858e700fd18", BlsPublicKey: "71f94154fd273f9e406856220f6b595cc5801c613df42c58952dcec2f808eeb275b2ecbc2df4c0b6305a5ef43e295c14"}, {Index: "85", Address: "one10vy4gdzga08vhenqke36x67fjqukyzk6d4hrqw", BlsPriKey: "d9d7b89c882727d92f232be10cf0a3d118422e9512b0531548e8072cb9354806", BlsPublicKey: "445ef889e5f294f1a5d231ff0de6fc25f228145c36d813084c9aa5e33bbae0b73cc71efa16b88f0490a80660564d2293", Updated: "harmony"},
{Index: "86", Address: "0x56151Cda1F9574543d0f5F0b2c33384dbfDf0fb7", BlsPriKey: "d69892c1bf461a46d2132dd2f55de7cb39927080dea56e2c1a38b5cc6cdfc73c", BlsPublicKey: "201a8fb7b9e42facc2343d20520a22c96906abd7b978a7ef9e431f02cd10eb47ae41c6a79c9ad6229389e05e27eeeb03"}, {Index: "86", Address: "one1mtvr4rtt7zwp5xwz65razvy54vzxn57y8wd9um", BlsPriKey: "35631f61bb4225e1185454802e2611538b931e4493071923ee8e7da6dda7f33c", BlsPublicKey: "af4cbb5b185473e667b1004a59aaf265430cd6fc1d2578bf32e88e9c639cd839790f12bf4e58b9f685daf3b9ab3d7001", Updated: "harmony"},
{Index: "87", Address: "0x2fCb9070db07EB2b63B73a2a9D019dF45530f65D", BlsPriKey: "7355f51383eb59b8fdca818fc74a573de64ab0381c526b46a83599dc8026230a", BlsPublicKey: "633a36a8ac7d3a5f4089c125f89d2fd525f8365da3a9bb55d213f9e46584009745156c8d92d9d89aa9b6bfa5aad0508e"}, {Index: "87", Address: "one1ahw70lq9sqqygs8f7zdrvw7zd796w5n48hc5xh", BlsPriKey: "0933aab0cf0a15d213c7f5fb2a56336921060b6fcb90ac2ec61cf2d13d185226", BlsPublicKey: "f0d6a1d78c4817e451fb242b7501b23a9e9b5214e6ae8695a00e344a2f6662dad96baeb4f983d5613404795fae71e80d", Updated: "harmony"},
{Index: "88", Address: "one129s9f828f538jrjca2wwlwphsl5k8rlzjdeacq", BlsPriKey: "d7828305a2604c459b3174bb1ae7e5b77a0c378435caba2a7578748147da7c17", BlsPublicKey: "d0f2ff9397b34660d15f5e369c6d8fd8ad85d610e612a4041bf7e6fd07afcdfae137116df2b5c3c4d2bfbd112fc6db0e"}, {Index: "88", Address: "one129s9f828f538jrjca2wwlwphsl5k8rlzjdeacq", BlsPriKey: "c56b16437455c67eb884d82a945be089d1c3f8b355b64258aaaaaa58dcb2a834", BlsPublicKey: "eb4d1c141fc6319f32710212b78b88a045ce95437025bfca56ec399cdcd469d1c49081025f859e09b35249cf2cc6bf06", Updated: "was in code and updated from sheet"},
{Index: "89", Address: "one1hrdt5e5lepygmj2vfthjzauuc9085lpnfjhha4", BlsPriKey: "be3e3134482aa89c4e75961c015e9ac3ee564575690117368c653f042804f73d", BlsPublicKey: "ad70e6d77a63ea67a6b2a4eb6df7ab20f155e2b9f534b2b73e9d03f49e476be7e89c7cd49508f724bb5a6549f8dd2189"}, {Index: "89", Address: "one1zjjul68lhv8hef7angwvakmc37evv8gppraft0", BlsPriKey: "9b528e658b80066eb1785b4cfc2218c103741aba52ae1ccb0dbb88b270d8c41a", BlsPublicKey: "7bc9bc157947a0ce4b8ed57161b0e873947098f25f3d82dacae3e53fdd0a845638c797b12bea1929f1bfe9088fbe7c07", Updated: "harmony"},
{Index: "90", Address: "one1hrg76d5743k5x8jmyu4zyn232fzdexf06w32s3", BlsPriKey: "0b668c5c142e847537516a2d43f5524db3f31110e5e0d868728a83833004d73a", BlsPublicKey: "3370bbd9c2750dc27e34c4521b70edea9f3dc5fd0a3a60a1730bda498a96ea3423adbbfa6e0ecb3ded590ef6ac9de496"}, {Index: "90", Address: "one10746sav20n8h4gm3sevj3vfydtpv6vpksv2065", BlsPriKey: "0c9cfdafc47b0aebcfc94fb6cf6d40ef8c1a12fe1c4250e949a4bebc821a623f", BlsPublicKey: "ca95dc563fc804a9ec409894d03a4e7613edee62d4cf07e0c4b444d563e38fcd84b8a0ecffc76f46c6c0025b1f45948c", Updated: "harmony"},
{Index: "91", Address: "one1cfjewan3unl3d90qpg2f8j56k8vgzyy9hxe56m", BlsPriKey: "94e6ca09e165e81e649395583958f452c3be2dd7f6421d624e445fc6ddd58d5f", BlsPublicKey: "916bbe51751a4ecdf22d87ec7d398ff094224c04461261a421325444f67542639778323c2b3236cf74cb28599d7f6c10"}, {Index: "91", Address: "one13gu3wvxga2jkpg72k5m4lye6nktxzu7a5vsnec", BlsPriKey: "078d029f3101cabfadfcb8aed4bdb0827cd495e829ebeed78548625f3cc8d466", BlsPublicKey: "8fb9de02c7f9b8baad2905994c6d9f559b99a72fdd6aa20eab692bb1fcc25c712ba7410d4dae8dad182d714e80d7d787", Updated: "harmony"},
{Index: "92", Address: "one18683c2vyr4xdv4wd3ley8wd250pnmxn346s4qq", BlsPriKey: "0d60c1b650d86a835ab555287c5475588a5a729bb57abade10a95c877c82313b", BlsPublicKey: "a95de45bb64fa540e78f4fe5c0ae24e8d9ba5f9bd78ec16382df55bfe4ff7c097596af70f85d97f8ba6a58c13e5c780c"}, {Index: "92", Address: "one18683c2vyr4xdv4wd3ley8wd250pnmxn346s4qq", BlsPriKey: "7faca2722bc9a7d578e6ee053d9eb57796a91ee937b1184543a00c9587577526", BlsPublicKey: "63413f65e2955e98ef71f517a5d21c5c30c1182b9e6e669205df74fbeeba88e058fb239ada9d29603bcb2df613ca2d8e", Updated: "harmony"},
{Index: "93", Address: "one1ypqdwd3y0gy2yl4z2we4x9shhfpuxq7xxk0ak2", BlsPriKey: "70d73a85dff49f9f0012827aeb61ecdafc19928c642f4532829a963d76b72d24", BlsPublicKey: "e6acd7d2f34ed78ce7f4f47b6fbb0b4fd09baeae77c27529baeb3566cb14c229fc512846e5821b28b7542f94c8693709"}, {Index: "93", Address: "one10ha8a07jpxlla89gcmlu7k9j3ra3sqdyq2c620", BlsPriKey: "e1d8c272972f6a52fa9fb868f99ed60669f6f9f89e235ff0d82bef022f29b31c", BlsPublicKey: "03ed4996a4808aa1c9672dcbde4262311fcddd9d291e7f0b96d5fa4968831454479584d0ce0c2471557f506f189cd388", Updated: "harmony"},
{Index: "94", Address: "one1z2ecd52ulnf9qm942tqr4f527h5f3klaajfgg8", BlsPriKey: "205e447c0a5a18b09c96eac2048b9686cc17d03771988e6849235f01e0488106", BlsPublicKey: "34700da988abd54d498d02e89a6eb1ab1ca02888f4b1b552bde13b7db447fbc48f49c25566352d7095a53ef3523d3802"}, {Index: "94", Address: "one1hrdt5e5lepygmj2vfthjzauuc9085lpnfjhha4", BlsPriKey: "457b34ae2c6a04e2299712cbe1a53d7c17d6a9c3474d0d2cedd77680a8180623", BlsPublicKey: "c6404146b9655332ff5e2ad4877c2689658bb037e7da9a4114806a2ba8b1c9bd0af8062e4cba22e68466336f3dba6a0e", Updated: "harmony"},
{Index: "95", Address: "one1j347aqndcvu5qmlrd5fdt22u25clkzccnu4kvz", BlsPriKey: "f5c70520bd3ed30ba9d187764eaa197f099a6a869cb8b7f228b220e6d4388d00", BlsPublicKey: "e21322f16917f6933d78b63fd578b60c1201c852c6df9a6c9e493b98caf968a6bc022b90bb6215eee106892070317b91"}, {Index: "95", Address: "one1hrg76d5743k5x8jmyu4zyn232fzdexf06w32s3", BlsPriKey: "9e46c88259e4082297e824c76779b9856cbbd5f94b54acab2656b96a878bb00f", BlsPublicKey: "930590243131160f8007ddf0a8107c01c5600c57b8b107ae21a9c0a7e71ebdbcf820230f7cd2a00eeb2777f9f62fed03", Updated: "harmony"},
{Index: "96", Address: "one149aw0kne2qwyxkxhz9v0msgf00lndvvdjne4rq", BlsPriKey: "c7aec9264d1d69b74aedd8aff7c8a1dfddda451cf8eefe10e92289fff7b77e13", BlsPublicKey: "9cc4af9768565ddcfb8f6b5df7322da4bc4a0d4fe94fc0f0971b4da83c3bc95d1eaa91a6407609ec86aacec9e08bf591"}, {Index: "96", Address: "one149aw0kne2qwyxkxhz9v0msgf00lndvvdjne4rq", BlsPriKey: "518f9b3674a0807b84a3f8bebf0585a4204552162d1013486d22b1215b348961", BlsPublicKey: "00508bf582665b3c75442231397f061ac3b9fedc5edc3343a465d9153ea7eca5ed97c33c097ac7a75533a420149dc492", Updated: "was in code and updated from sheet"},
{Index: "97", Address: "one1df4tldae3amrkyrf96tg9pqccjvkjetattl4w8", BlsPriKey: "4b8b3043a94fda72f40ce4db801142cbec07bc30367c372bcba5048da55fa86b", BlsPublicKey: "d9a1a3bf2337fdc1726db613eccc17ca590e588f3d82b86d2abd319cf26eb95010efaf0166468cedb64840de41cdf698"}, {Index: "97", Address: "one1df4tldae3amrkyrf96tg9pqccjvkjetattl4w8", BlsPriKey: "a96bea1010cec516dd489d18d490507a41223099789bf6fd068cb17d2f66eb4d", BlsPublicKey: "3fc212e1bb7594018c0882d2aa1818e9401209f8e41cdee613fd6bec096872d55c01ea02e091063f6ce49dbca49b3f14", Updated: "was in code and updated from sheet"},
{Index: "98", Address: "one19jtrujyvqdvdn9wm9tne5d4vrwvy36y69msczs", BlsPriKey: "11a3343067e71d0ee61fce30838522590e545dbfaadfe66668255f97a9db863b", BlsPublicKey: "0d9a92c946d3d1bb59ae39e1769304fe769aeac623bab37b4d4cf81f8891f2efd629916591e48ea39fd853532831d48d"}, {Index: "98", Address: "one19jtrujyvqdvdn9wm9tne5d4vrwvy36y69msczs", BlsPriKey: "7c088b58aaabab8a16b5996db32ef8a0dba8b99202b6271f4322f3f4b23bd009", BlsPublicKey: "bbd0b173ace9f35c22eb80fe4673497f55c7039f089a3444a329f760f0d4a335927bb7d94a70b817c405351570f3d411", Updated: "was in code and updated from sheet"},
{Index: "99", Address: "one1f40kwnze67gepxl2m5tpljr93exrhpehcfjs6k", BlsPriKey: "454f45068b784632b15db9c212a49b9d3b642f6b5ca53d09b86fcb2c84a11738", BlsPublicKey: "92f967adc41fa54735dfee2087bf0743ec9b4793174f8cd515c366daa20a3dfd71a62f7658f9ebcbf2013d3fa22f8f96", Updated: "harmony"},
} }

@ -7,6 +7,7 @@ import (
"strings" "strings"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
) )
@ -19,6 +20,7 @@ type DeployAccount struct {
BlsPriKey string // account private BLS key (To be removed) BlsPriKey string // account private BLS key (To be removed)
BlsPublicKey string // account public BLS key BlsPublicKey string // account public BLS key
ShardID uint32 // shardID of the account ShardID uint32 // shardID of the account
Updated string
} }
func (d DeployAccount) String() string { func (d DeployAccount) String() string {
@ -39,13 +41,14 @@ func BeaconAccountPriKey() *ecdsa.PrivateKey {
// the account address could be from GenesisAccounts or from GenesisFNAccounts // the account address could be from GenesisAccounts or from GenesisFNAccounts
// the account index can be used to determin the shard of the account // the account index can be used to determin the shard of the account
func FindAccount(address string) (int, *DeployAccount) { func FindAccount(address string) (int, *DeployAccount) {
addr := common.ParseAddr(address)
for i, acc := range GenesisAccounts { for i, acc := range GenesisAccounts {
if address == acc.Address { if addr == common.ParseAddr(acc.Address) {
return i, &acc return i, &acc
} }
} }
for i, acc := range GenesisFNAccounts { for i, acc := range GenesisFNAccounts {
if address == acc.Address { if addr == common.ParseAddr(acc.Address) {
return i + 8, &acc return i + 8, &acc
} }
} }

@ -2,8 +2,14 @@ package utils
import ( import (
"fmt" "fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"syscall" "syscall"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -19,3 +25,56 @@ func AskForPassphrase(prompt string) string {
return password return password
} }
// readAllAsString reads the entire file contents as a string.
func readAllAsString(r io.Reader) (data string, err error) {
bytes, err := ioutil.ReadAll(r)
return string(bytes), err
}
// GetPassphraseFromSource reads a passphrase such as a key-encrypting one
// non-interactively from the given source.
//
// The source can be "pass:password", "env:var", "file:pathname", "fd:number",
// or "stdin". See “PASS PHRASE ARGUMENTS” section of openssl(1) for details.
func GetPassphraseFromSource(src string) (pass string, err error) {
switch src {
case "stdin":
return readAllAsString(os.Stdin)
}
methodArg := strings.SplitN(src, ":", 2)
if len(methodArg) < 2 {
return "", errors.Errorf("invalid passphrase reading method %#v", src)
}
method := methodArg[0]
arg := methodArg[1]
switch method {
case "pass":
return arg, nil
case "env":
pass, ok := os.LookupEnv(arg)
if !ok {
return "", errors.Errorf("environment variable %#v undefined", arg)
}
return pass, nil
case "file":
f, err := os.Open(arg)
if err != nil {
return "", errors.Wrapf(err, "cannot open file %#v", arg)
}
defer func() { _ = f.Close() }()
return readAllAsString(f)
case "fd":
fd, err := strconv.ParseUint(arg, 10, 0)
if err != nil {
return "", errors.Wrapf(err, "invalid fd literal %#v", arg)
}
f := os.NewFile(uintptr(fd), "(passphrase-source)")
if f == nil {
return "", errors.Errorf("cannot open fd %#v", fd)
}
defer func() { _ = f.Close() }()
return readAllAsString(f)
}
return "", errors.Errorf("invalid passphrase reading method %#v", method)
}

@ -0,0 +1,44 @@
package utils
import (
"fmt"
"os"
"testing"
"github.com/pkg/errors"
testutils "github.com/harmony-one/harmony/internal/utils/testing"
)
func exerciseGetPassphraseFromSource(t *testing.T, source, expected string) {
if actual, err := GetPassphraseFromSource(source); err != nil {
t.Fatal(errors.Wrap(err, "cannot read passphrase"))
} else if actual != expected {
t.Errorf("expected passphrase %#v; got %#v", expected, actual)
}
}
func TestGetPassphraseFromSource_Pass(t *testing.T) {
exerciseGetPassphraseFromSource(t, "pass:hello world", "hello world")
}
func TestGetPassphraseFromSource_File(t *testing.T) {
expected := "\nhello world\n"
t.Run("stdin", func(t *testing.T) {
f := testutils.NewTempFileWithContents(t, []byte(expected))
savedStdin := os.Stdin
defer func() { os.Stdin = savedStdin }()
os.Stdin = f
exerciseGetPassphraseFromSource(t, "stdin", expected)
})
t.Run("file", func(t *testing.T) {
f := testutils.NewTempFileWithContents(t, []byte(expected))
defer testutils.CloseAndRemoveTempFile(t, f)
exerciseGetPassphraseFromSource(t, "file:"+f.Name(), expected)
})
t.Run("fd", func(t *testing.T) {
f := testutils.NewTempFileWithContents(t, []byte(expected))
defer testutils.CloseAndRemoveTempFile(t, f)
exerciseGetPassphraseFromSource(t, fmt.Sprintf("fd:%d", f.Fd()), expected)
})
}

@ -0,0 +1,46 @@
package testutils
import (
"io"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/pkg/errors"
)
// NewTempFile creates a new, empty temp file for testing. Errors are fatal.
func NewTempFile(t *testing.T) *os.File {
pattern := strings.ReplaceAll(t.Name(), string(os.PathSeparator), "_")
f, err := ioutil.TempFile("", pattern)
if err != nil {
t.Fatal(errors.Wrap(err, "cannot create temp file"))
}
return f
}
// NewTempFileWithContents creates a new, empty temp file for testing,
// with the given contents. The read/write offset is set to the beginning.
// Errors are fatal.
func NewTempFileWithContents(t *testing.T, contents []byte) *os.File {
f := NewTempFile(t)
if _, err := f.Write(contents); err != nil {
t.Fatal(errors.Wrapf(err, "cannot write contents into %s", f.Name()))
}
if _, err := f.Seek(0, io.SeekStart); err != nil {
t.Fatal(errors.Wrapf(err, "cannot rewind test file %s", f.Name()))
}
return f
}
// CloseAndRemoveTempFile closes/removes the temp file. Errors are logged.
func CloseAndRemoveTempFile(t *testing.T, f *os.File) {
fn := f.Name()
if err := f.Close(); err != nil {
t.Log(errors.Wrapf(err, "cannot close test file %s", fn))
}
if err := os.Remove(fn); err != nil {
t.Log(errors.Wrapf(err, "cannot remove test file %s", fn))
}
}

@ -424,7 +424,8 @@ func (node *Node) InitShardState(isGenesis bool) (err error) {
} }
getLogger().Info("initialized shard state", "numPubKeys", len(pubKeys)) getLogger().Info("initialized shard state", "numPubKeys", len(pubKeys))
node.Consensus.UpdatePublicKeys(pubKeys) node.Consensus.UpdatePublicKeys(pubKeys)
node.DRand.UpdatePublicKeys(pubKeys) // TODO: Disable drand. Currently drand isn't functioning but we want to compeletely turn it off for full protection.
// node.DRand.UpdatePublicKeys(pubKeys)
return nil return nil
} }

@ -448,9 +448,9 @@ func (node *Node) broadcastEpochShardState(newBlock *types.Block) error {
func (node *Node) AddNewBlock(newBlock *types.Block) { func (node *Node) AddNewBlock(newBlock *types.Block) {
blockNum, err := node.Blockchain().InsertChain([]*types.Block{newBlock}) blockNum, err := node.Blockchain().InsertChain([]*types.Block{newBlock})
if err != nil { if err != nil {
utils.GetLogInstance().Debug("Error adding new block to blockchain", "blockNum", blockNum, "hash", newBlock.Header().Hash(), "Error", err) utils.GetLogInstance().Debug("Error Adding new block to blockchain", "blockNum", blockNum, "hash", newBlock.Header().Hash(), "Error", err)
} else { } else {
utils.GetLogInstance().Info("adding new block to blockchain", "blockNum", blockNum, "hash", newBlock.Header().Hash(), "by node", node.SelfPeer) utils.GetLogInstance().Info("Added New Block to Blockchain!!!", "blockNum", blockNum, "hash", newBlock.Header().Hash(), "by node", node.SelfPeer)
} }
} }
@ -490,11 +490,11 @@ func (node *Node) pingMessageHandler(msgPayload []byte, sender string) int {
node.host.ConnectHostPeer(*peer) node.host.ConnectHostPeer(*peer)
if ping.Node.Role == proto_node.ClientRole { if ping.Node.Role == proto_node.ClientRole {
utils.GetLogInstance().Info("Add Client Peer to Node", "PubKey", node.Consensus.PubKey.SerializeToHexStr(), "Client", peer) utils.GetLogInstance().Info("Add Client Peer to Node", "Client", peer)
node.ClientPeer = peer node.ClientPeer = peer
} else { } else {
node.AddPeers([]*p2p.Peer{peer}) node.AddPeers([]*p2p.Peer{peer})
utils.GetLogInstance().Info("Add Peer to Node", "PubKey", node.Consensus.PubKey.SerializeToHexStr(), "Peer", peer, "# Peers", len(node.Consensus.PublicKeys)) utils.GetLogInstance().Info("Add Peer to Node", "Peer", peer, "# Peers", len(node.Consensus.PublicKeys))
} }
return 1 return 1
@ -518,12 +518,12 @@ func (node *Node) SendPongMessage() {
// no peers, wait for another tick // no peers, wait for another tick
if numPeersNow == 0 { if numPeersNow == 0 {
utils.GetLogInstance().Info("[PONG] no peers, continue", "numPeers", numPeers, "numPeersNow", numPeersNow) utils.GetLogInstance().Info("[PONG] No peers, continue", "numPeers", numPeers, "numPeersNow", numPeersNow)
continue continue
} }
// new peers added // new peers added
if numPeersNow != numPeers { if numPeersNow != numPeers {
utils.GetLogInstance().Info("[PONG] different number of peers", "numPeers", numPeers, "numPeersNow", numPeersNow) utils.GetLogInstance().Info("[PONG] Different number of peers", "numPeers", numPeers, "numPeersNow", numPeersNow)
sentMessage = false sentMessage = false
} else { } else {
// stable number of peers, sent the pong message // stable number of peers, sent the pong message
@ -533,10 +533,10 @@ func (node *Node) SendPongMessage() {
buffer := pong.ConstructPongMessage() buffer := pong.ConstructPongMessage()
err := node.host.SendMessageToGroups([]p2p.GroupID{node.NodeConfig.GetShardGroupID()}, host.ConstructP2pMessage(byte(0), buffer)) err := node.host.SendMessageToGroups([]p2p.GroupID{node.NodeConfig.GetShardGroupID()}, host.ConstructP2pMessage(byte(0), buffer))
if err != nil { if err != nil {
utils.GetLogInstance().Error("[PONG] failed to send pong message", "group", node.NodeConfig.GetShardGroupID()) utils.GetLogInstance().Error("[PONG] Failed to send pong message", "group", node.NodeConfig.GetShardGroupID())
continue continue
} else { } else {
utils.GetLogInstance().Info("[PONG] sent pong message to", "group", node.NodeConfig.GetShardGroupID(), "# nodes", numPeersNow) utils.GetLogInstance().Info("[PONG] Sent pong message to", "group", node.NodeConfig.GetShardGroupID(), "# nodes", numPeersNow)
} }
sentMessage = true sentMessage = true
@ -544,7 +544,7 @@ func (node *Node) SendPongMessage() {
if firstTime { if firstTime {
// Leader stops sending ping message // Leader stops sending ping message
node.serviceManager.TakeAction(&service.Action{Action: service.Stop, ServiceType: service.PeerDiscovery}) node.serviceManager.TakeAction(&service.Action{Action: service.Stop, ServiceType: service.PeerDiscovery})
utils.GetLogInstance().Info("[PONG] startConsensus") utils.GetLogInstance().Info("[PONG] StartConsensus")
node.startConsensus <- struct{}{} node.startConsensus <- struct{}{}
firstTime = false firstTime = false
} }
@ -559,10 +559,10 @@ func (node *Node) SendPongMessage() {
buffer := pong.ConstructPongMessage() buffer := pong.ConstructPongMessage()
err := node.host.SendMessageToGroups([]p2p.GroupID{node.NodeConfig.GetShardGroupID()}, host.ConstructP2pMessage(byte(0), buffer)) err := node.host.SendMessageToGroups([]p2p.GroupID{node.NodeConfig.GetShardGroupID()}, host.ConstructP2pMessage(byte(0), buffer))
if err != nil { if err != nil {
utils.GetLogInstance().Error("[PONG] failed to send regular pong message", "group", node.NodeConfig.GetShardGroupID()) utils.GetLogInstance().Error("[PONG] Failed to send regular pong message", "group", node.NodeConfig.GetShardGroupID())
continue continue
} else { } else {
utils.GetLogInstance().Info("[PONG] sent regular pong message to", "group", node.NodeConfig.GetShardGroupID(), "# nodes", len(peers)) utils.GetLogInstance().Info("[PONG] Sent regular pong message to", "group", node.NodeConfig.GetShardGroupID(), "# nodes", len(peers))
} }
} }
} }
@ -805,10 +805,5 @@ func getBinaryPath() (argv0 string, err error) {
// ConsensusMessageHandler passes received message in node_handler to consensus // ConsensusMessageHandler passes received message in node_handler to consensus
func (node *Node) ConsensusMessageHandler(msgPayload []byte) { func (node *Node) ConsensusMessageHandler(msgPayload []byte) {
select { node.Consensus.MsgChan <- msgPayload
case node.Consensus.MsgChan <- msgPayload:
case <-time.After(consensusTimeout):
//utils.GetLogInstance().Debug("[Consensus] ConsensusMessageHandler timeout", "duration", consensusTimeout, "msgPayload", len(msgPayload))
}
return
} }

@ -17,7 +17,7 @@ import (
const ( const (
DefaultThreshold = 1 DefaultThreshold = 1
FirstTimeThreshold = 2 FirstTimeThreshold = 2
ConsensusTimeOut = 10 ConsensusTimeOut = 30
PeriodicBlock = 1 * time.Second PeriodicBlock = 1 * time.Second
BlockPeriod = 10 * time.Second BlockPeriod = 10 * time.Second
) )
@ -34,13 +34,24 @@ func (node *Node) WaitForConsensusReadyv2(readySignal chan struct{}, stopChan ch
time.Sleep(30 * time.Second) // Wait for other nodes to be ready (test-only) time.Sleep(30 * time.Second) // Wait for other nodes to be ready (test-only)
firstTime := true firstTime := true
timeoutCount := 0
var newBlock *types.Block
for { for {
// keep waiting for Consensus ready // keep waiting for Consensus ready
select { select {
case <-stopChan: case <-stopChan:
utils.GetLogInstance().Debug("Consensus propose new block: STOPPED!") utils.GetLogInstance().Debug("Consensus new block proposal: STOPPED!")
return return
case <-time.After(ConsensusTimeOut * time.Second):
utils.GetLogInstance().Debug("Consensus timeout, retry!", "count", timeoutCount)
if node.Consensus.PubKey.IsEqual(node.Consensus.LeaderPubKey) {
node.Consensus.ResetState()
timeoutCount++
if newBlock != nil {
// Send the new block to Consensus so it can be confirmed.
node.BlockChannel <- newBlock
}
}
case <-readySignal: case <-readySignal:
firstTry := true firstTry := true
deadline := time.Now().Add(BlockPeriod) deadline := time.Now().Add(BlockPeriod)
@ -68,19 +79,18 @@ func (node *Node) WaitForConsensusReadyv2(readySignal chan struct{}, stopChan ch
ctxerror.New("cannot commit transactions"). ctxerror.New("cannot commit transactions").
WithCause(err)) WithCause(err))
} }
block, err := node.Worker.Commit() newBlock, err := node.Worker.Commit()
if err != nil { if err != nil {
ctxerror.Log15(utils.GetLogger().Error, ctxerror.Log15(utils.GetLogger().Error,
ctxerror.New("cannot commit new block"). ctxerror.New("cannot commit new block").
WithCause(err)) WithCause(err))
continue continue
} else if err := node.proposeShardState(block); err != nil { } else if err := node.proposeShardState(newBlock); err != nil {
ctxerror.Log15(utils.GetLogger().Error, ctxerror.Log15(utils.GetLogger().Error,
ctxerror.New("cannot add shard state"). ctxerror.New("cannot add shard state").
WithCause(err)) WithCause(err))
} else { } else {
newBlock := block utils.GetLogInstance().Debug("Successfully proposed new block", "blockNum", newBlock.NumberU64(), "numTxs", newBlock.Transactions().Len())
utils.GetLogInstance().Debug("Successfully proposed new block", "blockNum", block.NumberU64(), "numTxs", block.Transactions().Len())
// Send the new block to Consensus so it can be confirmed. // Send the new block to Consensus so it can be confirmed.
node.BlockChannel <- newBlock node.BlockChannel <- newBlock

@ -111,6 +111,7 @@ SyncingLoop:
node.stateMutex.Lock() node.stateMutex.Lock()
node.State = NodeNotInSync node.State = NodeNotInSync
node.stateMutex.Unlock() node.stateMutex.Unlock()
node.Consensus.BlocksNotSynchronized()
node.stateSync.SyncLoop(bc, worker, willJoinConsensus, false) node.stateSync.SyncLoop(bc, worker, willJoinConsensus, false)
if willJoinConsensus { if willJoinConsensus {
node.stateMutex.Lock() node.stateMutex.Lock()

@ -9,7 +9,6 @@ import (
"github.com/harmony-one/harmony/api/service/discovery" "github.com/harmony-one/harmony/api/service/discovery"
"github.com/harmony-one/harmony/api/service/explorer" "github.com/harmony-one/harmony/api/service/explorer"
"github.com/harmony-one/harmony/api/service/networkinfo" "github.com/harmony-one/harmony/api/service/networkinfo"
"github.com/harmony-one/harmony/api/service/randomness"
"github.com/harmony-one/harmony/api/service/staking" "github.com/harmony-one/harmony/api/service/staking"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
@ -63,7 +62,9 @@ func (node *Node) setupForBeaconLeader() {
// Register new block service. // Register new block service.
node.serviceManager.RegisterService(service.BlockProposal, blockproposal.New(node.Consensus.ReadySignal, node.WaitForConsensusReadyv2)) node.serviceManager.RegisterService(service.BlockProposal, blockproposal.New(node.Consensus.ReadySignal, node.WaitForConsensusReadyv2))
// Register randomness service // Register randomness service
node.serviceManager.RegisterService(service.Randomness, randomness.New(node.DRand)) // TODO: Disable drand. Currently drand isn't functioning but we want to compeletely turn it off for full protection.
// Enable it back after mainnet.
// node.serviceManager.RegisterService(service.Randomness, randomness.New(node.DRand))
// Register explorer service. // Register explorer service.
node.serviceManager.RegisterService(service.SupportExplorer, explorer.New(&node.SelfPeer, node.Consensus.GetNodeIDs, node.GetBalanceOfAddress)) node.serviceManager.RegisterService(service.SupportExplorer, explorer.New(&node.SelfPeer, node.Consensus.GetNodeIDs, node.GetBalanceOfAddress))
} }

@ -22,5 +22,9 @@ type Peer struct {
} }
func (p Peer) String() string { func (p Peer) String() string {
return fmt.Sprintf("%s/%s[%d]", net.JoinHostPort(p.IP, p.Port), p.PeerID, len(p.Addrs)) BlsPubKey := "nil"
if p.ConsensusPubKey != nil {
BlsPubKey = p.ConsensusPubKey.SerializeToHexStr()
}
return fmt.Sprintf("BlsPubKey:%s-%s/%s[%d]", BlsPubKey, net.JoinHostPort(p.IP, p.Port), p.PeerID, len(p.Addrs))
} }

@ -21,17 +21,6 @@ err() {
exit "${code}" exit "${code}"
} }
function killnode() {
local port=$1
if [ -n "port" ]; then
pid=$(/bin/ps -fu $USER | grep "harmony" | grep "$port" | awk '{print $2}')
echo "killing node with port: $port"
$DRYRUN kill -9 $pid 2> /dev/null
echo "node with port: $port is killed"
fi
}
# https://www.linuxjournal.com/content/validating-ip-address-bash-script # https://www.linuxjournal.com/content/validating-ip-address-bash-script
function valid_ip() function valid_ip()
{ {
@ -54,10 +43,9 @@ function myip() {
# get ipv4 address only, right now only support ipv4 addresses # get ipv4 address only, right now only support ipv4 addresses
PUB_IP=$(dig -4 @resolver1.opendns.com ANY myip.opendns.com +short) PUB_IP=$(dig -4 @resolver1.opendns.com ANY myip.opendns.com +short)
if valid_ip $PUB_IP; then if valid_ip $PUB_IP; then
echo MYIP = $PUB_IP msg "public IP address autodetected: $PUB_IP"
else else
echo NO valid public IP found: $PUB_IP err 1 "NO valid public IP found: $PUB_IP"
exit 1
fi fi
} }
@ -89,42 +77,43 @@ function setup_env
add_env /etc/pam.d/common-session "session required pam_limits.so" add_env /etc/pam.d/common-session "session required pam_limits.so"
} }
function find_harmony_process
{
unset -v pidfile pid
pidfile="harmony-${PUB_IP}.pid"
pid=$!
echo "${pid}" > "${pidfile}"
ps -f -p "${pid}"
}
######## main ######### ######## main #########
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" msg "this script must be run as root"
echo Please use \"sudo $0\" msg please use \"sudo $0\"
exit 1 exit 1
fi fi
usage() { print_usage() {
msg "$@"
cat <<- ENDEND cat <<- ENDEND
usage: ${progname} [-b] account_address usage: ${progname} [-1ch] account_address
-c back up database/logs and start clean -c back up database/logs and start clean
(use only when directed by Harmony)
-1 do not loop; run once and exit
-h print this help and exit
ENDEND ENDEND
}
usage() {
msg "$@"
print_usage >&2
exit 64 # EX_USAGE exit 64 # EX_USAGE
} }
unset start_clean unset start_clean loop
start_clean=false start_clean=false
loop=true
unset OPTIND OPTARG opt unset OPTIND OPTARG opt
OPTIND=1 OPTIND=1
while getopts :c opt while getopts :1ch opt
do do
case "${opt}" in case "${opt}" in
'?') usage "unrecognized option -${OPTARG}";; '?') usage "unrecognized option -${OPTARG}";;
':') usage "missing argument for -${OPTARG}";; ':') usage "missing argument for -${OPTARG}";;
c) start_clean=true;; c) start_clean=true;;
1) loop=false;;
h) print_usage; exit 0;;
*) err 70 "unhandled option -${OPTARG}";; # EX_SOFTWARE *) err 70 "unhandled option -${OPTARG}";; # EX_SOFTWARE
esac esac
done done
@ -147,8 +136,6 @@ case $# in
;; ;;
esac esac
killnode
BUCKET=pub.harmony.one BUCKET=pub.harmony.one
OS=$(uname -s) OS=$(uname -s)
REL=drum REL=drum
@ -167,11 +154,18 @@ for bin in "${BIN[@]}"; do
rm -f ${bin} rm -f ${bin}
done done
# download all the binaries download_binaries() {
for bin in "${BIN[@]}"; do local outdir
curl http://${BUCKET}.s3.amazonaws.com/${FOLDER}${bin} -o ${bin} outdir="${1:-.}"
done mkdir -p "${outdir}"
chmod +x harmony for bin in "${BIN[@]}"; do
curl http://${BUCKET}.s3.amazonaws.com/${FOLDER}${bin} -o "${outdir}/${bin}" || return $?
done
chmod +x "${outdir}/harmony"
(cd "${outdir}" && exec openssl sha256 "${BIN[@]}") > "${outdir}/harmony-checksums.txt"
}
download_binaries || err 69 "initial node software update failed"
NODE_PORT=9000 NODE_PORT=9000
PUB_IP= PUB_IP=
@ -200,22 +194,123 @@ then
fi fi
mkdir -p latest mkdir -p latest
echo "############### Running Harmony Process ###############" unset -v check_update_pid
if [ "$OS" == "Linux" ]; then
# Run Harmony Node
LD_LIBRARY_PATH=$(pwd) ./harmony -bootnodes $BN_MA -ip $PUB_IP -port $NODE_PORT -is_genesis -is_archival -accounts $IDX
else
DYLD_FALLBACK_LIBRARY_PATH=$(pwd) ./harmony -bootnodes $BN_MA -ip $PUB_IP -port $NODE_PORT -is_genesis -is_archival -accounts $IDX
fi
find_harmony_process cleanup() {
echo local trap_sig kill_sig
echo
# echo Please run the following command to inspect the log trap_sig="${1:-EXIT}"
# echo "tail -f harmony-${PUB_IP}.log"
kill_sig="${trap_sig}"
case "${kill_sig}" in
0|EXIT|2|INT) kill_sig=TERM;;
esac
case "${check_update_pid+set}" in
set)
msg "terminating update checker (pid ${check_update_pid})"
kill -${kill_sig} "${check_update_pid}"
;;
esac
}
unset -v trap_sigs trap_sig
trap_sigs="EXIT HUP INT TERM"
trap_func() {
local trap_sig="${1-EXIT}"
case "${trap_sig}" in
0|EXIT) msg "exiting";;
*) msg "received SIG${trap_sig}";;
esac
trap - ${trap_sigs}
cleanup "${trap_sig}"
case "${trap_sig}" in
""|0|EXIT) ;;
*) kill -"${trap_sig}" "$$";;
esac
}
for trap_sig in ${trap_sigs}
do
trap "trap_func ${trap_sig}" ${trap_sig}
done
# Kill the given PID, ensuring that it is a child of this script ($$).
kill_child() {
local pid
pid="${1}"
case $(($(ps -oppid= -p"${pid}" || :) + 0)) in
$$) ;;
*) return 1;;
esac
msg "killing pid ${pid}"
kill "${pid}"
}
# Kill nodes that are direct child of this script (pid $$),
# i.e. run directly from main loop.
kill_node() {
local pids pid delay
msg "finding node processes that are our children"
pids=$(
ps axcwwo "pid=,ppid=,command=" |
awk -v me=$$ '$2 == me && $3 == "harmony" { print $1; }'
)
msg "found node processes: ${pids:-"<none>"}"
for pid in ${pids}
do
delay=0
while kill_child ${pid}
do
sleep ${delay}
delay=1
done
msg "pid ${pid} no longer running"
done
}
{
while :
do
msg "re-downloading binaries in 5m"
sleep 300
while ! download_binaries staging
do
msg "staging download failed; retrying in 30s"
sleep 30
done
if diff staging/harmony-checksums.txt harmony-checksums.txt
then
msg "binaries did not change"
continue
fi
msg "binaries changed; moving from staging into main"
(cd staging; exec mv harmony-checksums.txt "${BIN[@]}" ..) || continue
msg "binaries updated, killing node to restart"
kill_node
done
} > harmony-update.out 2>&1 &
check_update_pid=$!
unset -v passphrase
read -rsp "Enter passphrase for account ${IDX}: " passphrase
echo echo
echo You may use \"sudo pkill harmony\" to terminate running harmony node program.
trap killnode SIGINT SIGTERM while :
do
msg "############### Running Harmony Process ###############"
if [ "$OS" == "Linux" ]; then
# Run Harmony Node
echo -n "${passphrase}" | LD_LIBRARY_PATH=$(pwd) ./harmony -bootnodes $BN_MA -ip $PUB_IP -port $NODE_PORT -is_genesis -is_archival -accounts $IDX -pass stdin
else
echo -n "${passphrase}" | DYLD_FALLBACK_LIBRARY_PATH=$(pwd) ./harmony -bootnodes $BN_MA -ip $PUB_IP -port $NODE_PORT -is_genesis -is_archival -accounts $IDX -pass stdin
fi || msg "node process finished with status $?"
${loop} || break
msg "restarting in 10s..."
sleep 10
done

Loading…
Cancel
Save