Skip to content

Commit

Permalink
use new raft get leader ID
Browse files Browse the repository at this point in the history
  • Loading branch information
agouin committed Nov 15, 2023
1 parent e421787 commit 6a73411
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 222 deletions.
6 changes: 5 additions & 1 deletion cmd/horcrux/cmd/threshold.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ func NewThresholdValidator(

for _, c := range thresholdCfg.Cosigners {
if c.ShardID != security.GetID() {
rc, err := signer.NewRemoteCosigner(c.ShardID, c.P2PAddr)
if err != nil {
return nil, nil, fmt.Errorf("failed to initialize remote cosigner: %w", err)
}
remoteCosigners = append(
remoteCosigners,
signer.NewRemoteCosigner(c.ShardID, c.P2PAddr),
rc,
)
} else {
p2pListen = c.P2PAddr
Expand Down
2 changes: 1 addition & 1 deletion proto/strangelove/horcrux/cosigner.proto
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ message TransferLeadershipResponse {
message GetLeaderRequest {}

message GetLeaderResponse {
string leader = 1;
int32 leader = 1;
}

message PingRequest {}
Expand Down
11 changes: 11 additions & 0 deletions signer/cosigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ type Cosigner interface {
SetNoncesAndSign(ctx context.Context, req CosignerSetNoncesAndSignRequest) (*CosignerSignResponse, error)
}

type Cosigners []Cosigner

func (cosigners Cosigners) GetByID(id int) Cosigner {
for _, cosigner := range cosigners {
if cosigner.GetID() == id {
return cosigner
}
}
return nil
}

// CosignerSignRequest is sent to a co-signer to obtain their signature for the SignBytes
// The SignBytes should be a serialized block
type CosignerSignRequest struct {
Expand Down
2 changes: 1 addition & 1 deletion signer/cosigner_grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (rpc *CosignerGRPCServer) GetLeader(
*proto.GetLeaderRequest,
) (*proto.GetLeaderResponse, error) {
leader := rpc.raftStore.GetLeader()
return &proto.GetLeaderResponse{Leader: string(leader)}, nil
return &proto.GetLeaderResponse{Leader: int32(leader)}, nil
}

func (rpc *CosignerGRPCServer) Ping(context.Context, *proto.PingRequest) (*proto.PingResponse, error) {
Expand Down
6 changes: 3 additions & 3 deletions signer/leader.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ type Leader interface {
// IsLeader returns true if the cosigner is the leader.
IsLeader() bool

// SignBlock asks the leader to manage the signing of a block.
SignBlock(CosignerSignBlockRequest) (*CosignerSignBlockResponse, error)

// ShareSigned shares the last signed state with the other cosigners.
ShareSigned(lss ChainSignStateConsensus) error

// Get current leader
GetLeader() int
}
35 changes: 2 additions & 33 deletions signer/leader_mock.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package signer

import (
"context"
"errors"
"sync"
"time"
)

var _ Leader = (*MockLeader)(nil)
Expand All @@ -28,36 +25,8 @@ func (m *MockLeader) SetLeader(tv *ThresholdValidator) {
m.leader = tv
}

func (m *MockLeader) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlockResponse, error) {
var l *ThresholdValidator
for i := 0; i < 30; i++ {
m.mu.Lock()
l = m.leader
m.mu.Unlock()
if l != nil {
break
}
time.Sleep(100 * time.Millisecond)
}

if l == nil {
return nil, errors.New("timed out waiting for leader election to complete")
}

block := Block{
Height: req.Block.Height,
Round: req.Block.Round,
Step: req.Block.Step,
SignBytes: req.Block.SignBytes,
Timestamp: req.Block.Timestamp,
}
res, _, err := l.Sign(context.TODO(), req.ChainID, block)
if err != nil {
return nil, err
}
return &CosignerSignBlockResponse{
Signature: res,
}, nil
func (m *MockLeader) GetLeader() int {
return m.id
}

func (m *MockLeader) ShareSigned(_ ChainSignStateConsensus) error {
Expand Down
126 changes: 55 additions & 71 deletions signer/proto/cosigner.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 0 additions & 46 deletions signer/raft_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ package signer

import (
"encoding/json"
"errors"
"time"

"github.com/strangelove-ventures/horcrux/signer/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

const (
Expand Down Expand Up @@ -46,43 +40,3 @@ func (f *fsm) handleLSSEvent(value string) {
_ = f.thresholdValidator.SaveLastSignedState(lss.ChainID, lss.SignStateConsensus)
_ = f.cosigner.SaveLastSignedState(lss.ChainID, lss.SignStateConsensus)
}

func (s *RaftStore) getLeaderGRPCClient() (proto.CosignerClient, *grpc.ClientConn, error) {
var leader string
for i := 0; i < 30; i++ {
leader = string(s.GetLeader())
if leader != "" {
break
}
time.Sleep(100 * time.Millisecond)
}
if leader == "" {
totalRaftLeaderElectiontimeout.Inc()
return nil, nil, errors.New("timed out waiting for leader election to complete")
}
conn, err := grpc.Dial(leader, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, nil, err
}
return proto.NewCosignerClient(conn), conn, nil
}

func (s *RaftStore) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlockResponse, error) {
client, conn, err := s.getLeaderGRPCClient()
if err != nil {
return nil, err
}
defer conn.Close()
context, cancelFunc := getContext()
defer cancelFunc()
res, err := client.SignBlock(context, &proto.SignBlockRequest{
ChainID: req.ChainID,
Block: req.Block.ToProto(),
})
if err != nil {
return nil, err
}
return &CosignerSignBlockResponse{
Signature: res.GetSignature(),
}, nil
}
15 changes: 12 additions & 3 deletions signer/raft_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"net/url"
"os"
"path/filepath"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -287,11 +288,19 @@ func (s *RaftStore) IsLeader() bool {
return s.raft.State() == raft.Leader
}

func (s *RaftStore) GetLeader() raft.ServerAddress {
func (s *RaftStore) GetLeader() int {
if s == nil || s.raft == nil {
return ""
return -1
}
return s.raft.Leader()
_, leaderID := s.raft.LeaderWithID()
if leaderID == "" {
return -1
}
id, err := strconv.Atoi(string(leaderID))
if err != nil {
return -1
}
return id
}

func (s *RaftStore) ShareSigned(lss ChainSignStateConsensus) error {
Expand Down
Loading

0 comments on commit 6a73411

Please sign in to comment.