Browse Source

raft: int64 -> uint64

Xiang Li 11 years ago
parent
commit
af5b8c6c44
8 changed files with 294 additions and 288 deletions
  1. 31 31
      raft/log.go
  2. 33 33
      raft/log_test.go
  3. 11 11
      raft/node.go
  4. 10 10
      raft/node_test.go
  5. 37 37
      raft/raft.go
  6. 104 98
      raft/raft_test.go
  7. 42 42
      raft/raftpb/raft.pb.go
  8. 26 26
      raft/raftpb/raft.proto

+ 31 - 31
raft/log.go

@@ -12,15 +12,15 @@ const (
 
 type raftLog struct {
 	ents      []pb.Entry
-	unstable  int64
-	committed int64
-	applied   int64
-	offset    int64
+	unstable  uint64
+	committed uint64
+	applied   uint64
+	offset    uint64
 	snapshot  pb.Snapshot
 
 	// want a compact after the number of entries exceeds the threshold
 	// TODO(xiangli) size might be a better criteria
-	compactThreshold int64
+	compactThreshold uint64
 }
 
 func newLog() *raftLog {
@@ -39,20 +39,20 @@ func (l *raftLog) isEmpty() bool {
 
 func (l *raftLog) load(ents []pb.Entry) {
 	l.ents = ents
-	l.unstable = l.offset + int64(len(ents))
+	l.unstable = l.offset + uint64(len(ents))
 }
 
 func (l *raftLog) String() string {
 	return fmt.Sprintf("offset=%d committed=%d applied=%d len(ents)=%d", l.offset, l.committed, l.applied, len(l.ents))
 }
 
-func (l *raftLog) maybeAppend(index, logTerm, committed int64, ents ...pb.Entry) bool {
-	lastnewi := index + int64(len(ents))
+func (l *raftLog) maybeAppend(index, logTerm, committed uint64, ents ...pb.Entry) bool {
+	lastnewi := index + uint64(len(ents))
 	if l.matchTerm(index, logTerm) {
 		from := index + 1
 		ci := l.findConflict(from, ents)
 		switch {
-		case ci == -1:
+		case ci == 0:
 		case ci <= l.committed:
 			panic("conflict with committed entry")
 		default:
@@ -68,19 +68,19 @@ func (l *raftLog) maybeAppend(index, logTerm, committed int64, ents ...pb.Entry)
 	return false
 }
 
-func (l *raftLog) append(after int64, ents ...pb.Entry) int64 {
+func (l *raftLog) append(after uint64, ents ...pb.Entry) uint64 {
 	l.ents = append(l.slice(l.offset, after+1), ents...)
 	l.unstable = min(l.unstable, after+1)
 	return l.lastIndex()
 }
 
-func (l *raftLog) findConflict(from int64, ents []pb.Entry) int64 {
+func (l *raftLog) findConflict(from uint64, ents []pb.Entry) uint64 {
 	for i, ne := range ents {
-		if oe := l.at(from + int64(i)); oe == nil || oe.Term != ne.Term {
-			return from + int64(i)
+		if oe := l.at(from + uint64(i)); oe == nil || oe.Term != ne.Term {
+			return from + uint64(i)
 		}
 	}
-	return -1
+	return 0
 }
 
 func (l *raftLog) unstableEnts() []pb.Entry {
@@ -112,18 +112,18 @@ func (l *raftLog) resetNextEnts() {
 	}
 }
 
-func (l *raftLog) lastIndex() int64 {
-	return int64(len(l.ents)) - 1 + l.offset
+func (l *raftLog) lastIndex() uint64 {
+	return uint64(len(l.ents)) - 1 + l.offset
 }
 
-func (l *raftLog) term(i int64) int64 {
+func (l *raftLog) term(i uint64) uint64 {
 	if e := l.at(i); e != nil {
 		return e.Term
 	}
-	return -1
+	return 0
 }
 
-func (l *raftLog) entries(i int64) []pb.Entry {
+func (l *raftLog) entries(i uint64) []pb.Entry {
 	// never send out the first entry
 	// first entry is only used for matching
 	// prevLogTerm
@@ -133,19 +133,19 @@ func (l *raftLog) entries(i int64) []pb.Entry {
 	return l.slice(i, l.lastIndex()+1)
 }
 
-func (l *raftLog) isUpToDate(i, term int64) bool {
+func (l *raftLog) isUpToDate(i, term uint64) bool {
 	e := l.at(l.lastIndex())
 	return term > e.Term || (term == e.Term && i >= l.lastIndex())
 }
 
-func (l *raftLog) matchTerm(i, term int64) bool {
+func (l *raftLog) matchTerm(i, term uint64) bool {
 	if e := l.at(i); e != nil {
 		return e.Term == term
 	}
 	return false
 }
 
-func (l *raftLog) maybeCommit(maxIndex, term int64) bool {
+func (l *raftLog) maybeCommit(maxIndex, term uint64) bool {
 	if maxIndex > l.committed && l.term(maxIndex) == term {
 		l.committed = maxIndex
 		return true
@@ -158,17 +158,17 @@ func (l *raftLog) maybeCommit(maxIndex, term int64) bool {
 // i must be not smaller than the index of the first entry
 // and not greater than the index of the last entry.
 // the number of entries after compaction will be returned.
-func (l *raftLog) compact(i int64) int64 {
+func (l *raftLog) compact(i uint64) uint64 {
 	if l.isOutOfAppliedBounds(i) {
 		panic(fmt.Sprintf("compact %d out of bounds [%d:%d]", i, l.offset, l.applied))
 	}
 	l.ents = l.slice(i, l.lastIndex()+1)
 	l.unstable = max(i+1, l.unstable)
 	l.offset = i
-	return int64(len(l.ents))
+	return uint64(len(l.ents))
 }
 
-func (l *raftLog) snap(d []byte, index, term int64, nodes []int64, removed []int64) {
+func (l *raftLog) snap(d []byte, index, term uint64, nodes []uint64, removed []uint64) {
 	l.snapshot = pb.Snapshot{
 		Data:         d,
 		Nodes:        nodes,
@@ -191,7 +191,7 @@ func (l *raftLog) restore(s pb.Snapshot) {
 	l.snapshot = s
 }
 
-func (l *raftLog) at(i int64) *pb.Entry {
+func (l *raftLog) at(i uint64) *pb.Entry {
 	if l.isOutOfBounds(i) {
 		return nil
 	}
@@ -199,7 +199,7 @@ func (l *raftLog) at(i int64) *pb.Entry {
 }
 
 // slice returns a slice of log entries from lo through hi-1, inclusive.
-func (l *raftLog) slice(lo int64, hi int64) []pb.Entry {
+func (l *raftLog) slice(lo uint64, hi uint64) []pb.Entry {
 	if lo >= hi {
 		return nil
 	}
@@ -209,28 +209,28 @@ func (l *raftLog) slice(lo int64, hi int64) []pb.Entry {
 	return l.ents[lo-l.offset : hi-l.offset]
 }
 
-func (l *raftLog) isOutOfBounds(i int64) bool {
+func (l *raftLog) isOutOfBounds(i uint64) bool {
 	if i < l.offset || i > l.lastIndex() {
 		return true
 	}
 	return false
 }
 
-func (l *raftLog) isOutOfAppliedBounds(i int64) bool {
+func (l *raftLog) isOutOfAppliedBounds(i uint64) bool {
 	if i < l.offset || i > l.applied {
 		return true
 	}
 	return false
 }
 
-func min(a, b int64) int64 {
+func min(a, b uint64) uint64 {
 	if a > b {
 		return b
 	}
 	return a
 }
 
-func max(a, b int64) int64 {
+func max(a, b uint64) uint64 {
 	if a > b {
 		return a
 	}

+ 33 - 33
raft/log_test.go

@@ -14,13 +14,13 @@ import (
 // 2.Append any new entries not already in the log
 func TestAppend(t *testing.T) {
 	previousEnts := []pb.Entry{{Term: 1}, {Term: 2}}
-	previousUnstable := int64(3)
+	previousUnstable := uint64(3)
 	tests := []struct {
-		after     int64
+		after     uint64
 		ents      []pb.Entry
-		windex    int64
+		windex    uint64
 		wents     []pb.Entry
-		wunstable int64
+		wunstable uint64
 	}{
 		{
 			2,
@@ -74,13 +74,13 @@ func TestAppend(t *testing.T) {
 // TestCompactionSideEffects ensures that all the log related funcationality works correctly after
 // a compaction.
 func TestCompactionSideEffects(t *testing.T) {
-	var i int64
-	lastIndex := int64(1000)
+	var i uint64
+	lastIndex := uint64(1000)
 	lastTerm := lastIndex
 	raftLog := newLog()
 
 	for i = 0; i < lastIndex; i++ {
-		raftLog.append(int64(i), pb.Entry{Term: int64(i + 1), Index: int64(i + 1)})
+		raftLog.append(uint64(i), pb.Entry{Term: uint64(i + 1), Index: uint64(i + 1)})
 	}
 	raftLog.maybeCommit(lastIndex, lastTerm)
 	raftLog.resetNextEnts()
@@ -126,9 +126,9 @@ func TestCompactionSideEffects(t *testing.T) {
 func TestUnstableEnts(t *testing.T) {
 	previousEnts := []pb.Entry{{Term: 1, Index: 1}, {Term: 2, Index: 2}}
 	tests := []struct {
-		unstable  int64
+		unstable  uint64
 		wents     []pb.Entry
-		wunstable int64
+		wunstable uint64
 	}{
 		{3, nil, 3},
 		{1, previousEnts, 3},
@@ -152,18 +152,18 @@ func TestUnstableEnts(t *testing.T) {
 //TestCompaction ensures that the number of log entreis is correct after compactions.
 func TestCompaction(t *testing.T) {
 	tests := []struct {
-		applied   int64
-		lastIndex int64
-		compact   []int64
+		applied   uint64
+		lastIndex uint64
+		compact   []uint64
 		wleft     []int
 		wallow    bool
 	}{
 		// out of upper bound
-		{1000, 1000, []int64{1001}, []int{-1}, false},
-		{1000, 1000, []int64{300, 500, 800, 900}, []int{701, 501, 201, 101}, true},
+		{1000, 1000, []uint64{1001}, []int{-1}, false},
+		{1000, 1000, []uint64{300, 500, 800, 900}, []int{701, 501, 201, 101}, true},
 		// out of lower bound
-		{1000, 1000, []int64{300, 299}, []int{701, -1}, false},
-		{0, 1000, []int64{1}, []int{-1}, false},
+		{1000, 1000, []uint64{300, 299}, []int{701, -1}, false},
+		{0, 1000, []uint64{1}, []int{-1}, false},
 	}
 
 	for i, tt := range tests {
@@ -177,8 +177,8 @@ func TestCompaction(t *testing.T) {
 			}()
 
 			raftLog := newLog()
-			for i := int64(0); i < tt.lastIndex; i++ {
-				raftLog.append(int64(i), pb.Entry{})
+			for i := uint64(0); i < tt.lastIndex; i++ {
+				raftLog.append(uint64(i), pb.Entry{})
 			}
 			raftLog.maybeCommit(tt.applied, 0)
 			raftLog.resetNextEnts()
@@ -194,14 +194,14 @@ func TestCompaction(t *testing.T) {
 }
 
 func TestLogRestore(t *testing.T) {
-	var i int64
+	var i uint64
 	raftLog := newLog()
 	for i = 0; i < 100; i++ {
 		raftLog.append(i, pb.Entry{Term: i + 1})
 	}
 
-	index := int64(1000)
-	term := int64(1000)
+	index := uint64(1000)
+	term := uint64(1000)
 	raftLog.restore(pb.Snapshot{Index: index, Term: term})
 
 	// only has the guard entry
@@ -226,12 +226,12 @@ func TestLogRestore(t *testing.T) {
 }
 
 func TestIsOutOfBounds(t *testing.T) {
-	offset := int64(100)
-	num := int64(100)
+	offset := uint64(100)
+	num := uint64(100)
 	l := &raftLog{offset: offset, ents: make([]pb.Entry, num)}
 
 	tests := []struct {
-		index int64
+		index uint64
 		w     bool
 	}{
 		{offset - 1, true},
@@ -250,9 +250,9 @@ func TestIsOutOfBounds(t *testing.T) {
 }
 
 func TestAt(t *testing.T) {
-	var i int64
-	offset := int64(100)
-	num := int64(100)
+	var i uint64
+	offset := uint64(100)
+	num := uint64(100)
 
 	l := &raftLog{offset: offset}
 	for i = 0; i < num; i++ {
@@ -260,7 +260,7 @@ func TestAt(t *testing.T) {
 	}
 
 	tests := []struct {
-		index int64
+		index uint64
 		w     *pb.Entry
 	}{
 		{offset - 1, nil},
@@ -279,9 +279,9 @@ func TestAt(t *testing.T) {
 }
 
 func TestSlice(t *testing.T) {
-	var i int64
-	offset := int64(100)
-	num := int64(100)
+	var i uint64
+	offset := uint64(100)
+	num := uint64(100)
 
 	l := &raftLog{offset: offset}
 	for i = 0; i < num; i++ {
@@ -289,8 +289,8 @@ func TestSlice(t *testing.T) {
 	}
 
 	tests := []struct {
-		from int64
-		to   int64
+		from uint64
+		to   uint64
 		w    []pb.Entry
 	}{
 		{offset - 1, offset + 1, nil},

+ 11 - 11
raft/node.go

@@ -19,9 +19,9 @@ var (
 // SoftState provides state that is useful for logging and debugging.
 // The state is volatile and does not need to be persisted to the WAL.
 type SoftState struct {
-	Lead       int64
+	Lead       uint64
 	RaftState  StateType
-	Nodes      []int64
+	Nodes      []uint64
 	ShouldStop bool
 }
 
@@ -61,8 +61,8 @@ type Ready struct {
 }
 
 type compact struct {
-	index int64
-	nodes []int64
+	index uint64
+	nodes []uint64
 	data  []byte
 }
 
@@ -114,13 +114,13 @@ type Node interface {
 	// It is the caller's responsibility to ensure the given configuration
 	// and snapshot data match the actual point-in-time configuration and snapshot
 	// at the given index.
-	Compact(index int64, nodes []int64, d []byte)
+	Compact(index uint64, nodes []uint64, d []byte)
 }
 
 // StartNode returns a new Node given a unique raft id, a list of raft peers, and
 // the election and heartbeat timeouts in units of ticks.
 // It also builds ConfChangeAddNode entry for each peer and puts them at the head of the log.
-func StartNode(id int64, peers []int64, election, heartbeat int) Node {
+func StartNode(id uint64, peers []uint64, election, heartbeat int) Node {
 	n := newNode()
 	r := newRaft(id, peers, election, heartbeat)
 
@@ -131,10 +131,10 @@ func StartNode(id int64, peers []int64, election, heartbeat int) Node {
 		if err != nil {
 			panic("unexpected marshal error")
 		}
-		ents[i] = pb.Entry{Type: pb.EntryConfChange, Term: 1, Index: int64(i + 1), Data: data}
+		ents[i] = pb.Entry{Type: pb.EntryConfChange, Term: 1, Index: uint64(i + 1), Data: data}
 	}
 	r.raftLog.append(0, ents...)
-	r.raftLog.committed = int64(len(ents))
+	r.raftLog.committed = uint64(len(ents))
 
 	go n.run(r)
 	return &n
@@ -143,7 +143,7 @@ func StartNode(id int64, peers []int64, election, heartbeat int) Node {
 // RestartNode is identical to StartNode but takes an initial State and a slice
 // of entries. Generally this is used when restarting from a stable storage
 // log.
-func RestartNode(id int64, peers []int64, election, heartbeat int, snapshot *pb.Snapshot, st pb.HardState, ents []pb.Entry) Node {
+func RestartNode(id uint64, peers []uint64, election, heartbeat int, snapshot *pb.Snapshot, st pb.HardState, ents []pb.Entry) Node {
 	n := newNode()
 	r := newRaft(id, peers, election, heartbeat)
 	if snapshot != nil {
@@ -317,14 +317,14 @@ func (n *node) ApplyConfChange(cc pb.ConfChange) {
 	}
 }
 
-func (n *node) Compact(index int64, nodes []int64, d []byte) {
+func (n *node) Compact(index uint64, nodes []uint64, d []byte) {
 	select {
 	case n.compactc <- compact{index, nodes, d}:
 	case <-n.done:
 	}
 }
 
-func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState, prevSnapi int64) Ready {
+func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState, prevSnapi uint64) Ready {
 	rd := Ready{
 		Entries:          r.raftLog.unstableEnts(),
 		CommittedEntries: r.raftLog.nextEnts(),

+ 10 - 10
raft/node_test.go

@@ -18,10 +18,10 @@ func TestNodeStep(t *testing.T) {
 			propc: make(chan raftpb.Message, 1),
 			recvc: make(chan raftpb.Message, 1),
 		}
-		msgt := int64(i)
+		msgt := uint64(i)
 		n.Step(context.TODO(), raftpb.Message{Type: msgt})
 		// Proposal goes to proc chan. Others go to recvc chan.
-		if int64(i) == msgProp {
+		if uint64(i) == msgProp {
 			select {
 			case <-n.propc:
 			default:
@@ -96,7 +96,7 @@ func TestNodeStepUnblock(t *testing.T) {
 // who is the current leader.
 func TestBlockProposal(t *testing.T) {
 	n := newNode()
-	r := newRaft(1, []int64{1}, 10, 1)
+	r := newRaft(1, []uint64{1}, 10, 1)
 	go n.run(r)
 	defer n.Stop()
 
@@ -156,7 +156,7 @@ func TestNode(t *testing.T) {
 	}
 	wants := []Ready{
 		{
-			SoftState: &SoftState{Lead: 1, Nodes: []int64{1}, RaftState: StateLeader},
+			SoftState: &SoftState{Lead: 1, Nodes: []uint64{1}, RaftState: StateLeader},
 			HardState: raftpb.HardState{Term: 1, Commit: 2},
 			Entries: []raftpb.Entry{
 				{},
@@ -175,7 +175,7 @@ func TestNode(t *testing.T) {
 		},
 	}
 
-	n := StartNode(1, []int64{1}, 10, 1)
+	n := StartNode(1, []uint64{1}, 10, 1)
 	n.Campaign(ctx)
 	if g := <-n.Ready(); !reflect.DeepEqual(g, wants[0]) {
 		t.Errorf("#%d: g = %+v,\n             w   %+v", 1, g, wants[0])
@@ -207,7 +207,7 @@ func TestNodeRestart(t *testing.T) {
 		CommittedEntries: entries[1 : st.Commit+1],
 	}
 
-	n := RestartNode(1, []int64{1}, 10, 1, nil, st, entries)
+	n := RestartNode(1, []uint64{1}, 10, 1, nil, st, entries)
 	if g := <-n.Ready(); !reflect.DeepEqual(g, want) {
 		t.Errorf("g = %+v,\n             w   %+v", g, want)
 	}
@@ -224,7 +224,7 @@ func TestNodeRestart(t *testing.T) {
 func TestNodeCompact(t *testing.T) {
 	ctx := context.Background()
 	n := newNode()
-	r := newRaft(1, []int64{1}, 10, 1)
+	r := newRaft(1, []uint64{1}, 10, 1)
 	go n.run(r)
 
 	n.Campaign(ctx)
@@ -234,8 +234,8 @@ func TestNodeCompact(t *testing.T) {
 		Term:         1,
 		Index:        2, // one nop + one proposal
 		Data:         []byte("a snapshot"),
-		Nodes:        []int64{1},
-		RemovedNodes: []int64{},
+		Nodes:        []uint64{1},
+		RemovedNodes: []uint64{},
 	}
 
 	pkg.ForceGosched()
@@ -279,7 +279,7 @@ func TestSoftStateEqual(t *testing.T) {
 		{&SoftState{Lead: 1}, false},
 		{&SoftState{RaftState: StateLeader}, false},
 		{&SoftState{ShouldStop: true}, false},
-		{&SoftState{Nodes: []int64{1, 2}}, false},
+		{&SoftState{Nodes: []uint64{1, 2}}, false},
 	}
 	for i, tt := range tests {
 		if g := tt.st.equal(&SoftState{}); g != tt.we {

+ 37 - 37
raft/raft.go

@@ -10,12 +10,12 @@ import (
 )
 
 // None is a placeholder node ID used when there is no leader.
-const None int64 = 0
+const None uint64 = 0
 
-type messageType int64
+type messageType uint64
 
 const (
-	msgHup int64 = iota
+	msgHup uint64 = iota
 	msgBeat
 	msgProp
 	msgApp
@@ -39,7 +39,7 @@ var mtmap = [...]string{
 }
 
 func (mt messageType) String() string {
-	return mtmap[int64(mt)]
+	return mtmap[uint64(mt)]
 }
 
 var errNoLeader = errors.New("no leader")
@@ -52,7 +52,7 @@ const (
 )
 
 // StateType represents the role of a node in a cluster.
-type StateType int64
+type StateType uint64
 
 var stmap = [...]string{
 	"StateFollower",
@@ -61,21 +61,21 @@ var stmap = [...]string{
 }
 
 func (st StateType) String() string {
-	return stmap[int64(st)]
+	return stmap[uint64(st)]
 }
 
 type progress struct {
-	match, next int64
+	match, next uint64
 }
 
-func (pr *progress) update(n int64) {
+func (pr *progress) update(n uint64) {
 	pr.match = n
 	pr.next = n + 1
 }
 
 // maybeDecrTo returns false if the given to index comes from an out of order message.
 // Otherwise it decreases the progress next index and returns true.
-func (pr *progress) maybeDecrTo(to int64) bool {
+func (pr *progress) maybeDecrTo(to uint64) bool {
 	// the rejection must be stale if the
 	// progress has matched with follower
 	// or "to" does not match next - 1
@@ -94,7 +94,7 @@ func (pr *progress) String() string {
 }
 
 // int64Slice implements sort interface
-type int64Slice []int64
+type int64Slice []uint64
 
 func (p int64Slice) Len() int           { return len(p) }
 func (p int64Slice) Less(i, j int) bool { return p[i] < p[j] }
@@ -103,27 +103,27 @@ func (p int64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 type raft struct {
 	pb.HardState
 
-	id int64
+	id uint64
 
 	// the log
 	raftLog *raftLog
 
-	prs map[int64]*progress
+	prs map[uint64]*progress
 
 	state StateType
 
-	votes map[int64]bool
+	votes map[uint64]bool
 
 	msgs []pb.Message
 
 	// the leader id
-	lead int64
+	lead uint64
 
 	// New configuration is ignored if there exists unapplied configuration.
 	pendingConf bool
 
 	// TODO: need GC and recovery from snapshot
-	removed map[int64]bool
+	removed map[uint64]bool
 
 	elapsed          int // number of ticks since the last msg
 	heartbeatTimeout int
@@ -132,17 +132,17 @@ type raft struct {
 	step             stepFunc
 }
 
-func newRaft(id int64, peers []int64, election, heartbeat int) *raft {
+func newRaft(id uint64, peers []uint64, election, heartbeat int) *raft {
 	if id == None {
 		panic("cannot use none id")
 	}
-	rand.Seed(id)
+	rand.Seed(int64(id))
 	r := &raft{
 		id:               id,
 		lead:             None,
 		raftLog:          newLog(),
-		prs:              make(map[int64]*progress),
-		removed:          make(map[int64]bool),
+		prs:              make(map[uint64]*progress),
+		removed:          make(map[uint64]bool),
 		electionTimeout:  election,
 		heartbeatTimeout: heartbeat,
 	}
@@ -174,7 +174,7 @@ func (r *raft) String() string {
 	return s
 }
 
-func (r *raft) poll(id int64, v bool) (granted int) {
+func (r *raft) poll(id uint64, v bool) (granted int) {
 	if _, ok := r.votes[id]; !ok {
 		r.votes[id] = v
 	}
@@ -199,7 +199,7 @@ func (r *raft) send(m pb.Message) {
 }
 
 // sendAppend sends RRPC, with entries to the given peer.
-func (r *raft) sendAppend(to int64) {
+func (r *raft) sendAppend(to uint64) {
 	pr := r.prs[to]
 	m := pb.Message{}
 	m.To = to
@@ -217,7 +217,7 @@ func (r *raft) sendAppend(to int64) {
 }
 
 // sendHeartbeat sends an empty msgApp
-func (r *raft) sendHeartbeat(to int64) {
+func (r *raft) sendHeartbeat(to uint64) {
 	m := pb.Message{
 		To:   to,
 		Type: msgApp,
@@ -257,12 +257,12 @@ func (r *raft) maybeCommit() bool {
 	return r.raftLog.maybeCommit(mci, r.Term)
 }
 
-func (r *raft) reset(term int64) {
+func (r *raft) reset(term uint64) {
 	r.Term = term
 	r.lead = None
 	r.Vote = None
 	r.elapsed = 0
-	r.votes = make(map[int64]bool)
+	r.votes = make(map[uint64]bool)
 	for i := range r.prs {
 		r.prs[i] = &progress{next: r.raftLog.lastIndex() + 1}
 		if i == r.id {
@@ -306,7 +306,7 @@ func (r *raft) tickHeartbeat() {
 	}
 }
 
-func (r *raft) becomeFollower(term int64, lead int64) {
+func (r *raft) becomeFollower(term uint64, lead uint64) {
 	r.step = stepFollower
 	r.reset(term)
 	r.tick = r.tickElection
@@ -423,12 +423,12 @@ func (r *raft) handleSnapshot(m pb.Message) {
 	}
 }
 
-func (r *raft) addNode(id int64) {
+func (r *raft) addNode(id uint64) {
 	r.setProgress(id, 0, r.raftLog.lastIndex()+1)
 	r.pendingConf = false
 }
 
-func (r *raft) removeNode(id int64) {
+func (r *raft) removeNode(id uint64) {
 	r.delProgress(id)
 	r.pendingConf = false
 	r.removed[id] = true
@@ -519,7 +519,7 @@ func stepFollower(r *raft, m pb.Message) {
 	}
 }
 
-func (r *raft) compact(index int64, nodes []int64, d []byte) {
+func (r *raft) compact(index uint64, nodes []uint64, d []byte) {
 	if index > r.raftLog.applied {
 		panic(fmt.Sprintf("raft: compact index (%d) exceeds applied index (%d)", index, r.raftLog.applied))
 	}
@@ -538,7 +538,7 @@ func (r *raft) restore(s pb.Snapshot) bool {
 	}
 
 	r.raftLog.restore(s)
-	r.prs = make(map[int64]*progress)
+	r.prs = make(map[uint64]*progress)
 	for _, n := range s.Nodes {
 		if n == r.id {
 			r.setProgress(n, r.raftLog.lastIndex(), r.raftLog.lastIndex()+1)
@@ -546,14 +546,14 @@ func (r *raft) restore(s pb.Snapshot) bool {
 			r.setProgress(n, 0, r.raftLog.lastIndex()+1)
 		}
 	}
-	r.removed = make(map[int64]bool)
+	r.removed = make(map[uint64]bool)
 	for _, n := range s.RemovedNodes {
 		r.removed[n] = true
 	}
 	return true
 }
 
-func (r *raft) needSnapshot(i int64) bool {
+func (r *raft) needSnapshot(i uint64) bool {
 	if i < r.raftLog.offset {
 		if r.raftLog.snapshot.Term == 0 {
 			panic("need non-empty snapshot")
@@ -563,27 +563,27 @@ func (r *raft) needSnapshot(i int64) bool {
 	return false
 }
 
-func (r *raft) nodes() []int64 {
-	nodes := make([]int64, 0, len(r.prs))
+func (r *raft) nodes() []uint64 {
+	nodes := make([]uint64, 0, len(r.prs))
 	for k := range r.prs {
 		nodes = append(nodes, k)
 	}
 	return nodes
 }
 
-func (r *raft) removedNodes() []int64 {
-	removed := make([]int64, 0, len(r.removed))
+func (r *raft) removedNodes() []uint64 {
+	removed := make([]uint64, 0, len(r.removed))
 	for k := range r.removed {
 		removed = append(removed, k)
 	}
 	return removed
 }
 
-func (r *raft) setProgress(id, match, next int64) {
+func (r *raft) setProgress(id, match, next uint64) {
 	r.prs[id] = &progress{next: next, match: match}
 }
 
-func (r *raft) delProgress(id int64) {
+func (r *raft) delProgress(id uint64) {
 	delete(r.prs, id)
 }
 

+ 104 - 98
raft/raft_test.go

@@ -58,7 +58,7 @@ func TestLogReplication(t *testing.T) {
 	tests := []struct {
 		*network
 		msgs       []pb.Message
-		wcommitted int64
+		wcommitted uint64
 	}{
 		{
 			newNetwork(nil, nil, nil),
@@ -202,9 +202,9 @@ func TestCommitWithoutNewTermEntry(t *testing.T) {
 }
 
 func TestDuelingCandidates(t *testing.T) {
-	a := newRaft(-1, nil, 10, 1) // k, id are set later
-	b := newRaft(-1, nil, 10, 1)
-	c := newRaft(-1, nil, 10, 1)
+	a := newRaft(1, []uint64{1, 2, 3}, 10, 1)
+	b := newRaft(2, []uint64{1, 2, 3}, 10, 1)
+	c := newRaft(3, []uint64{1, 2, 3}, 10, 1)
 
 	nt := newNetwork(a, b, c)
 	nt.cut(1, 3)
@@ -219,7 +219,7 @@ func TestDuelingCandidates(t *testing.T) {
 	tests := []struct {
 		sm      *raft
 		state   StateType
-		term    int64
+		term    uint64
 		raftLog *raftLog
 	}{
 		{a, StateFollower, 2, wlog},
@@ -235,7 +235,7 @@ func TestDuelingCandidates(t *testing.T) {
 			t.Errorf("#%d: term = %d, want %d", i, g, tt.term)
 		}
 		base := ltoa(tt.raftLog)
-		if sm, ok := nt.peers[1+int64(i)].(*raft); ok {
+		if sm, ok := nt.peers[1+uint64(i)].(*raft); ok {
 			l := ltoa(sm.raftLog)
 			if g := diffu(base, l); g != "" {
 				t.Errorf("#%d: diff:\n%s", i, g)
@@ -411,15 +411,15 @@ func TestProposalByProxy(t *testing.T) {
 
 func TestCompact(t *testing.T) {
 	tests := []struct {
-		compacti int64
-		nodes    []int64
-		removed  []int64
+		compacti uint64
+		nodes    []uint64
+		removed  []uint64
 		snapd    []byte
 		wpanic   bool
 	}{
-		{1, []int64{1, 2, 3}, []int64{4, 5}, []byte("some data"), false},
-		{2, []int64{1, 2, 3}, []int64{4, 5}, []byte("some data"), false},
-		{4, []int64{1, 2, 3}, []int64{4, 5}, []byte("some data"), true}, // compact out of range
+		{1, []uint64{1, 2, 3}, []int64{4, 5}, []byte("some data"), false},
+		{2, []uint64{1, 2, 3}, []int64{4, 5}, []byte("some data"), false},
+		{4, []uint64{1, 2, 3}, []int64{4, 5}, []byte("some data"), true}, // compact out of range
 	}
 
 	for i, tt := range tests {
@@ -464,36 +464,36 @@ func TestCompact(t *testing.T) {
 
 func TestCommit(t *testing.T) {
 	tests := []struct {
-		matches []int64
+		matches []uint64
 		logs    []pb.Entry
-		smTerm  int64
-		w       int64
+		smTerm  uint64
+		w       uint64
 	}{
 		// single
-		{[]int64{1}, []pb.Entry{{}, {Term: 1}}, 1, 1},
-		{[]int64{1}, []pb.Entry{{}, {Term: 1}}, 2, 0},
-		{[]int64{2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
-		{[]int64{1}, []pb.Entry{{}, {Term: 2}}, 2, 1},
+		{[]uint64{1}, []pb.Entry{{}, {Term: 1}}, 1, 1},
+		{[]uint64{1}, []pb.Entry{{}, {Term: 1}}, 2, 0},
+		{[]uint64{2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
+		{[]uint64{1}, []pb.Entry{{}, {Term: 2}}, 2, 1},
 
 		// odd
-		{[]int64{2, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
-		{[]int64{2, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
-		{[]int64{2, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
-		{[]int64{2, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
+		{[]uint64{2, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
+		{[]uint64{2, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
+		{[]uint64{2, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
+		{[]uint64{2, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
 
 		// even
-		{[]int64{2, 1, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
-		{[]int64{2, 1, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
-		{[]int64{2, 1, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
-		{[]int64{2, 1, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
-		{[]int64{2, 1, 2, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
-		{[]int64{2, 1, 2, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
+		{[]uint64{2, 1, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
+		{[]uint64{2, 1, 1, 1}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
+		{[]uint64{2, 1, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 1, 1},
+		{[]uint64{2, 1, 1, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
+		{[]uint64{2, 1, 2, 2}, []pb.Entry{{}, {Term: 1}, {Term: 2}}, 2, 2},
+		{[]uint64{2, 1, 2, 2}, []pb.Entry{{}, {Term: 1}, {Term: 1}}, 2, 0},
 	}
 
 	for i, tt := range tests {
-		prs := make(map[int64]*progress)
+		prs := make(map[uint64]*progress)
 		for j := 0; j < len(tt.matches); j++ {
-			prs[int64(j)] = &progress{tt.matches[j], tt.matches[j] + 1}
+			prs[uint64(j)] = &progress{tt.matches[j], tt.matches[j] + 1}
 		}
 		sm := &raft{raftLog: &raftLog{ents: tt.logs}, prs: prs, HardState: pb.HardState{Term: tt.smTerm}}
 		sm.maybeCommit()
@@ -517,7 +517,7 @@ func TestIsElectionTimeout(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		sm := newRaft(1, []int64{1}, 10, 1)
+		sm := newRaft(1, []uint64{1}, 10, 1)
 		sm.elapsed = tt.elapse
 		c := 0
 		for j := 0; j < 10000; j++ {
@@ -542,7 +542,7 @@ func TestStepIgnoreOldTermMsg(t *testing.T) {
 	fakeStep := func(r *raft, m pb.Message) {
 		called = true
 	}
-	sm := newRaft(1, []int64{1}, 10, 1)
+	sm := newRaft(1, []uint64{1}, 10, 1)
 	sm.step = fakeStep
 	sm.Term = 2
 	sm.Step(pb.Message{Type: msgApp, Term: sm.Term - 1})
@@ -559,8 +559,8 @@ func TestStepIgnoreOldTermMsg(t *testing.T) {
 func TestHandleMsgApp(t *testing.T) {
 	tests := []struct {
 		m       pb.Message
-		wIndex  int64
-		wCommit int64
+		wIndex  uint64
+		wCommit uint64
 		wReject bool
 	}{
 		// Ensure 1
@@ -608,8 +608,8 @@ func TestHandleMsgApp(t *testing.T) {
 func TestRecvMsgVote(t *testing.T) {
 	tests := []struct {
 		state   StateType
-		i, term int64
-		voteFor int64
+		i, term uint64
+		voteFor uint64
 		wreject bool
 	}{
 		{StateFollower, 0, 0, None, true},
@@ -640,7 +640,7 @@ func TestRecvMsgVote(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		sm := newRaft(1, []int64{1}, 10, 1)
+		sm := newRaft(1, []uint64{1}, 10, 1)
 		sm.state = tt.state
 		switch tt.state {
 		case StateFollower:
@@ -671,12 +671,12 @@ func TestStateTransition(t *testing.T) {
 		from   StateType
 		to     StateType
 		wallow bool
-		wterm  int64
-		wlead  int64
+		wterm  uint64
+		wlead  uint64
 	}{
 		{StateFollower, StateFollower, true, 1, None},
 		{StateFollower, StateCandidate, true, 1, None},
-		{StateFollower, StateLeader, false, -1, None},
+		{StateFollower, StateLeader, false, 0, None},
 
 		{StateCandidate, StateFollower, true, 0, None},
 		{StateCandidate, StateCandidate, true, 1, None},
@@ -697,7 +697,7 @@ func TestStateTransition(t *testing.T) {
 				}
 			}()
 
-			sm := newRaft(1, []int64{1}, 10, 1)
+			sm := newRaft(1, []uint64{1}, 10, 1)
 			sm.state = tt.from
 
 			switch tt.to {
@@ -724,19 +724,19 @@ func TestAllServerStepdown(t *testing.T) {
 		state StateType
 
 		wstate StateType
-		wterm  int64
-		windex int64
+		wterm  uint64
+		windex uint64
 	}{
 		{StateFollower, StateFollower, 3, 1},
 		{StateCandidate, StateFollower, 3, 1},
 		{StateLeader, StateFollower, 3, 2},
 	}
 
-	tmsgTypes := [...]int64{msgVote, msgApp}
-	tterm := int64(3)
+	tmsgTypes := [...]uint64{msgVote, msgApp}
+	tterm := uint64(3)
 
 	for i, tt := range tests {
-		sm := newRaft(1, []int64{1, 2, 3}, 10, 1)
+		sm := newRaft(1, []uint64{1, 2, 3}, 10, 1)
 		switch tt.state {
 		case StateFollower:
 			sm.becomeFollower(1, None)
@@ -756,10 +756,10 @@ func TestAllServerStepdown(t *testing.T) {
 			if sm.Term != tt.wterm {
 				t.Errorf("#%d.%d term = %v , want %v", i, j, sm.Term, tt.wterm)
 			}
-			if int64(len(sm.raftLog.ents)) != tt.windex {
+			if uint64(len(sm.raftLog.ents)) != tt.windex {
 				t.Errorf("#%d.%d index = %v , want %v", i, j, len(sm.raftLog.ents), tt.windex)
 			}
-			wlead := int64(2)
+			wlead := uint64(2)
 			if msgType == msgVote {
 				wlead = None
 			}
@@ -772,11 +772,11 @@ func TestAllServerStepdown(t *testing.T) {
 
 func TestLeaderAppResp(t *testing.T) {
 	tests := []struct {
-		index      int64
+		index      uint64
 		reject     bool
 		wmsgNum    int
-		windex     int64
-		wcommitted int64
+		windex     uint64
+		wcommitted uint64
 	}{
 		{3, true, 0, 0, 0},  // stale resp; no replies
 		{2, true, 1, 1, 0},  // denied resp; leader does not commit; decrese next and send probing msg
@@ -786,7 +786,7 @@ func TestLeaderAppResp(t *testing.T) {
 	for i, tt := range tests {
 		// sm term is 1 after it becomes the leader.
 		// thus the last log term must be 1 to be committed.
-		sm := newRaft(1, []int64{1, 2, 3}, 10, 1)
+		sm := newRaft(1, []uint64{1, 2, 3}, 10, 1)
 		sm.raftLog = &raftLog{ents: []pb.Entry{{}, {Term: 0}, {Term: 1}}}
 		sm.becomeCandidate()
 		sm.becomeLeader()
@@ -811,14 +811,14 @@ func TestLeaderAppResp(t *testing.T) {
 // When the leader receives a heartbeat tick, it should
 // send a msgApp with m.Index = 0, m.LogTerm=0 and empty entries.
 func TestBcastBeat(t *testing.T) {
-	offset := int64(1000)
+	offset := uint64(1000)
 	// make a state machine with log.offset = 1000
 	s := pb.Snapshot{
 		Index: offset,
 		Term:  1,
-		Nodes: []int64{1, 2, 3},
+		Nodes: []uint64{1, 2, 3},
 	}
-	sm := newRaft(1, []int64{1, 2, 3}, 10, 1)
+	sm := newRaft(1, []uint64{1, 2, 3}, 10, 1)
 	sm.Term = 1
 	sm.restore(s)
 
@@ -833,7 +833,7 @@ func TestBcastBeat(t *testing.T) {
 	if len(msgs) != 2 {
 		t.Fatalf("len(msgs) = %v, want 1", len(msgs))
 	}
-	tomap := map[int64]bool{2: true, 3: true}
+	tomap := map[uint64]bool{2: true, 3: true}
 	for i, m := range msgs {
 		if m.Type != msgApp {
 			t.Fatalf("#%d: type = %v, want = %v", i, m.Type, msgApp)
@@ -868,7 +868,7 @@ func TestRecvMsgBeat(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		sm := newRaft(1, []int64{1, 2, 3}, 10, 1)
+		sm := newRaft(1, []uint64{1, 2, 3}, 10, 1)
 		sm.raftLog = &raftLog{ents: []pb.Entry{{}, {Term: 0}, {Term: 1}}}
 		sm.Term = 1
 		sm.state = tt.state
@@ -896,13 +896,19 @@ func TestRecvMsgBeat(t *testing.T) {
 
 func TestRestore(t *testing.T) {
 	s := pb.Snapshot{
+<<<<<<< HEAD
 		Index:        defaultCompactThreshold + 1,
 		Term:         defaultCompactThreshold + 1,
 		Nodes:        []int64{1, 2, 3},
 		RemovedNodes: []int64{4, 5},
+=======
+		Index: defaultCompactThreshold + 1,
+		Term:  defaultCompactThreshold + 1,
+		Nodes: []uint64{1, 2, 3},
+>>>>>>> raft: int64 -> uint64
 	}
 
-	sm := newRaft(1, []int64{1, 2}, 10, 1)
+	sm := newRaft(1, []uint64{1, 2}, 10, 1)
 	if ok := sm.restore(s); !ok {
 		t.Fatal("restore fail, want succeed")
 	}
@@ -936,9 +942,9 @@ func TestProvideSnap(t *testing.T) {
 	s := pb.Snapshot{
 		Index: defaultCompactThreshold + 1,
 		Term:  defaultCompactThreshold + 1,
-		Nodes: []int64{1, 2},
+		Nodes: []uint64{1, 2},
 	}
-	sm := newRaft(1, []int64{1}, 10, 1)
+	sm := newRaft(1, []uint64{1}, 10, 1)
 	// restore the statemachin from a snapshot
 	// so it has a compacted log and a snapshot
 	sm.restore(s)
@@ -965,11 +971,11 @@ func TestRestoreFromSnapMsg(t *testing.T) {
 	s := pb.Snapshot{
 		Index: defaultCompactThreshold + 1,
 		Term:  defaultCompactThreshold + 1,
-		Nodes: []int64{1, 2},
+		Nodes: []uint64{1, 2},
 	}
 	m := pb.Message{Type: msgSnap, From: 1, Term: 2, Snapshot: s}
 
-	sm := newRaft(2, []int64{1, 2}, 10, 1)
+	sm := newRaft(2, []uint64{1, 2}, 10, 1)
 	sm.Step(m)
 
 	if !reflect.DeepEqual(sm.raftLog.snapshot, s) {
@@ -1008,7 +1014,7 @@ func TestSlowNodeRestore(t *testing.T) {
 // it appends the entry to log and sets pendingConf to be true.
 func TestStepConfig(t *testing.T) {
 	// a raft that cannot make progress
-	r := newRaft(1, []int64{1, 2}, 10, 1)
+	r := newRaft(1, []uint64{1, 2}, 10, 1)
 	r.becomeCandidate()
 	r.becomeLeader()
 	index := r.raftLog.lastIndex()
@@ -1026,7 +1032,7 @@ func TestStepConfig(t *testing.T) {
 // the proposal and keep its original state.
 func TestStepIgnoreConfig(t *testing.T) {
 	// a raft that cannot make progress
-	r := newRaft(1, []int64{1, 2}, 10, 1)
+	r := newRaft(1, []uint64{1, 2}, 10, 1)
 	r.becomeCandidate()
 	r.becomeLeader()
 	r.Step(pb.Message{From: 1, To: 1, Type: msgProp, Entries: []pb.Entry{{Type: pb.EntryConfChange}}})
@@ -1052,7 +1058,7 @@ func TestRecoverPendingConfig(t *testing.T) {
 		{pb.EntryConfChange, true},
 	}
 	for i, tt := range tests {
-		r := newRaft(1, []int64{1, 2}, 10, 1)
+		r := newRaft(1, []uint64{1, 2}, 10, 1)
 		r.appendEntry(pb.Entry{Type: tt.entType})
 		r.becomeCandidate()
 		r.becomeLeader()
@@ -1071,7 +1077,7 @@ func TestRecoverDoublePendingConfig(t *testing.T) {
 				t.Errorf("expect panic, but nothing happens")
 			}
 		}()
-		r := newRaft(1, []int64{1, 2}, 10, 1)
+		r := newRaft(1, []uint64{1, 2}, 10, 1)
 		r.appendEntry(pb.Entry{Type: pb.EntryConfChange})
 		r.appendEntry(pb.Entry{Type: pb.EntryConfChange})
 		r.becomeCandidate()
@@ -1081,7 +1087,7 @@ func TestRecoverDoublePendingConfig(t *testing.T) {
 
 // TestAddNode tests that addNode could update pendingConf and nodes correctly.
 func TestAddNode(t *testing.T) {
-	r := newRaft(1, []int64{1}, 10, 1)
+	r := newRaft(1, []uint64{1}, 10, 1)
 	r.pendingConf = true
 	r.addNode(2)
 	if r.pendingConf != false {
@@ -1089,7 +1095,7 @@ func TestAddNode(t *testing.T) {
 	}
 	nodes := r.nodes()
 	sort.Sort(int64Slice(nodes))
-	wnodes := []int64{1, 2}
+	wnodes := []uint64{1, 2}
 	if !reflect.DeepEqual(nodes, wnodes) {
 		t.Errorf("nodes = %v, want %v", nodes, wnodes)
 	}
@@ -1098,17 +1104,17 @@ func TestAddNode(t *testing.T) {
 // TestRemoveNode tests that removeNode could update pendingConf, nodes and
 // and removed list correctly.
 func TestRemoveNode(t *testing.T) {
-	r := newRaft(1, []int64{1, 2}, 10, 1)
+	r := newRaft(1, []uint64{1, 2}, 10, 1)
 	r.pendingConf = true
 	r.removeNode(2)
 	if r.pendingConf != false {
 		t.Errorf("pendingConf = %v, want false", r.pendingConf)
 	}
-	w := []int64{1}
+	w := []uint64{1}
 	if g := r.nodes(); !reflect.DeepEqual(g, w) {
 		t.Errorf("nodes = %v, want %v", g, w)
 	}
-	wremoved := map[int64]bool{2: true}
+	wremoved := map[uint64]bool{2: true}
 	if !reflect.DeepEqual(r.removed, wremoved) {
 		t.Errorf("rmNodes = %v, want %v", r.removed, wremoved)
 	}
@@ -1121,13 +1127,13 @@ func TestRecvMsgDenied(t *testing.T) {
 	fakeStep := func(r *raft, m pb.Message) {
 		called = true
 	}
-	r := newRaft(1, []int64{1, 2}, 10, 1)
+	r := newRaft(1, []uint64{1, 2}, 10, 1)
 	r.step = fakeStep
 	r.Step(pb.Message{From: 2, Type: msgDenied})
 	if called != false {
 		t.Errorf("stepFunc called = %v , want %v", called, false)
 	}
-	wremoved := map[int64]bool{1: true}
+	wremoved := map[uint64]bool{1: true}
 	if !reflect.DeepEqual(r.removed, wremoved) {
 		t.Errorf("rmNodes = %v, want %v", r.removed, wremoved)
 	}
@@ -1138,7 +1144,7 @@ func TestRecvMsgDenied(t *testing.T) {
 // pass it to the actual stepX function.
 func TestRecvMsgFromRemovedNode(t *testing.T) {
 	tests := []struct {
-		from    int64
+		from    uint64
 		wmsgNum int
 	}{
 		{1, 0},
@@ -1149,7 +1155,7 @@ func TestRecvMsgFromRemovedNode(t *testing.T) {
 		fakeStep := func(r *raft, m pb.Message) {
 			called = true
 		}
-		r := newRaft(1, []int64{1}, 10, 1)
+		r := newRaft(1, []uint64{1}, 10, 1)
 		r.step = fakeStep
 		r.removeNode(tt.from)
 		r.Step(pb.Message{From: tt.from, Type: msgVote})
@@ -1168,18 +1174,18 @@ func TestRecvMsgFromRemovedNode(t *testing.T) {
 }
 
 func TestPromotable(t *testing.T) {
-	id := int64(1)
+	id := uint64(1)
 	tests := []struct {
-		peers []int64
+		peers []uint64
 		wp    bool
 	}{
-		{[]int64{1}, true},
-		{[]int64{1, 2, 3}, true},
-		{[]int64{}, false},
-		{[]int64{2, 3}, false},
+		{[]uint64{1}, true},
+		{[]uint64{1, 2, 3}, true},
+		{[]uint64{}, false},
+		{[]uint64{2, 3}, false},
 	}
 	for i, tt := range tests {
-		r := &raft{id: id, prs: make(map[int64]*progress)}
+		r := &raft{id: id, prs: make(map[uint64]*progress)}
 		for _, id := range tt.peers {
 			r.prs[id] = &progress{}
 		}
@@ -1189,7 +1195,7 @@ func TestPromotable(t *testing.T) {
 	}
 }
 
-func ents(terms ...int64) *raft {
+func ents(terms ...uint64) *raft {
 	ents := []pb.Entry{{}}
 	for _, term := range terms {
 		ents = append(ents, pb.Entry{Term: term})
@@ -1201,9 +1207,9 @@ func ents(terms ...int64) *raft {
 }
 
 type network struct {
-	peers   map[int64]Interface
+	peers   map[uint64]Interface
 	dropm   map[connem]float64
-	ignorem map[int64]bool
+	ignorem map[uint64]bool
 }
 
 // newNetwork initializes a network from peers.
@@ -1212,12 +1218,12 @@ type network struct {
 // When using stateMachine, the address list is always [0, n).
 func newNetwork(peers ...Interface) *network {
 	size := len(peers)
-	peerAddrs := make([]int64, size)
+	peerAddrs := make([]uint64, size)
 	for i := 0; i < size; i++ {
-		peerAddrs[i] = 1 + int64(i)
+		peerAddrs[i] = 1 + uint64(i)
 	}
 
-	npeers := make(map[int64]Interface, size)
+	npeers := make(map[uint64]Interface, size)
 
 	for i, p := range peers {
 		id := peerAddrs[i]
@@ -1227,7 +1233,7 @@ func newNetwork(peers ...Interface) *network {
 			npeers[id] = sm
 		case *raft:
 			v.id = id
-			v.prs = make(map[int64]*progress)
+			v.prs = make(map[uint64]*progress)
 			for i := 0; i < size; i++ {
 				v.prs[peerAddrs[i]] = &progress{}
 			}
@@ -1242,7 +1248,7 @@ func newNetwork(peers ...Interface) *network {
 	return &network{
 		peers:   npeers,
 		dropm:   make(map[connem]float64),
-		ignorem: make(map[int64]bool),
+		ignorem: make(map[uint64]bool),
 	}
 }
 
@@ -1255,18 +1261,18 @@ func (nw *network) send(msgs ...pb.Message) {
 	}
 }
 
-func (nw *network) drop(from, to int64, perc float64) {
+func (nw *network) drop(from, to uint64, perc float64) {
 	nw.dropm[connem{from, to}] = perc
 }
 
-func (nw *network) cut(one, other int64) {
+func (nw *network) cut(one, other uint64) {
 	nw.drop(one, other, 1)
 	nw.drop(other, one, 1)
 }
 
-func (nw *network) isolate(id int64) {
+func (nw *network) isolate(id uint64) {
 	for i := 0; i < len(nw.peers); i++ {
-		nid := int64(i) + 1
+		nid := uint64(i) + 1
 		if nid != id {
 			nw.drop(id, nid, 1.0)
 			nw.drop(nid, id, 1.0)
@@ -1274,13 +1280,13 @@ func (nw *network) isolate(id int64) {
 	}
 }
 
-func (nw *network) ignore(t int64) {
+func (nw *network) ignore(t uint64) {
 	nw.ignorem[t] = true
 }
 
 func (nw *network) recover() {
 	nw.dropm = make(map[connem]float64)
-	nw.ignorem = make(map[int64]bool)
+	nw.ignorem = make(map[uint64]bool)
 }
 
 func (nw *network) filter(msgs []pb.Message) []pb.Message {
@@ -1305,7 +1311,7 @@ func (nw *network) filter(msgs []pb.Message) []pb.Message {
 }
 
 type connem struct {
-	from, to int64
+	from, to uint64
 }
 
 type blackHole struct{}

+ 42 - 42
raft/raftpb/raft.pb.go

@@ -99,7 +99,7 @@ func (x *ConfChangeType) UnmarshalJSON(data []byte) error {
 }
 
 type Info struct {
-	ID               int64  `protobuf:"varint,1,req" json:"ID"`
+	ID               uint64 `protobuf:"varint,1,req" json:"ID"`
 	XXX_unrecognized []byte `json:"-"`
 }
 
@@ -109,8 +109,8 @@ func (*Info) ProtoMessage()    {}
 
 type Entry struct {
 	Type             EntryType `protobuf:"varint,1,req,enum=raftpb.EntryType" json:"Type"`
-	Term             int64     `protobuf:"varint,2,req" json:"Term"`
-	Index            int64     `protobuf:"varint,3,req" json:"Index"`
+	Term             uint64    `protobuf:"varint,2,req" json:"Term"`
+	Index            uint64    `protobuf:"varint,3,req" json:"Index"`
 	Data             []byte    `protobuf:"bytes,4,opt" json:"Data"`
 	XXX_unrecognized []byte    `json:"-"`
 }
@@ -120,12 +120,12 @@ func (m *Entry) String() string { return proto.CompactTextString(m) }
 func (*Entry) ProtoMessage()    {}
 
 type Snapshot struct {
-	Data             []byte  `protobuf:"bytes,1,req,name=data" json:"data"`
-	Nodes            []int64 `protobuf:"varint,2,rep,name=nodes" json:"nodes"`
-	Index            int64   `protobuf:"varint,3,req,name=index" json:"index"`
-	Term             int64   `protobuf:"varint,4,req,name=term" json:"term"`
-	RemovedNodes     []int64 `protobuf:"varint,5,rep,name=removed_nodes" json:"removed_nodes"`
-	XXX_unrecognized []byte  `json:"-"`
+	Data             []byte   `protobuf:"bytes,1,req,name=data" json:"data"`
+	Nodes            []uint64 `protobuf:"varint,2,rep,name=nodes" json:"nodes"`
+	Index            uint64   `protobuf:"varint,3,req,name=index" json:"index"`
+	Term             uint64   `protobuf:"varint,4,req,name=term" json:"term"`
+	RemovedNodes     []uint64 `protobuf:"varint,5,rep,name=removed_nodes" json:"removed_nodes"`
+	XXX_unrecognized []byte   `json:"-"`
 }
 
 func (m *Snapshot) Reset()         { *m = Snapshot{} }
@@ -133,14 +133,14 @@ func (m *Snapshot) String() string { return proto.CompactTextString(m) }
 func (*Snapshot) ProtoMessage()    {}
 
 type Message struct {
-	Type             int64    `protobuf:"varint,1,req,name=type" json:"type"`
-	To               int64    `protobuf:"varint,2,req,name=to" json:"to"`
-	From             int64    `protobuf:"varint,3,req,name=from" json:"from"`
-	Term             int64    `protobuf:"varint,4,req,name=term" json:"term"`
-	LogTerm          int64    `protobuf:"varint,5,req,name=logTerm" json:"logTerm"`
-	Index            int64    `protobuf:"varint,6,req,name=index" json:"index"`
+	Type             uint64   `protobuf:"varint,1,req,name=type" json:"type"`
+	To               uint64   `protobuf:"varint,2,req,name=to" json:"to"`
+	From             uint64   `protobuf:"varint,3,req,name=from" json:"from"`
+	Term             uint64   `protobuf:"varint,4,req,name=term" json:"term"`
+	LogTerm          uint64   `protobuf:"varint,5,req,name=logTerm" json:"logTerm"`
+	Index            uint64   `protobuf:"varint,6,req,name=index" json:"index"`
 	Entries          []Entry  `protobuf:"bytes,7,rep,name=entries" json:"entries"`
-	Commit           int64    `protobuf:"varint,8,req,name=commit" json:"commit"`
+	Commit           uint64   `protobuf:"varint,8,req,name=commit" json:"commit"`
 	Snapshot         Snapshot `protobuf:"bytes,9,req,name=snapshot" json:"snapshot"`
 	Reject           bool     `protobuf:"varint,10,req,name=reject" json:"reject"`
 	XXX_unrecognized []byte   `json:"-"`
@@ -151,9 +151,9 @@ func (m *Message) String() string { return proto.CompactTextString(m) }
 func (*Message) ProtoMessage()    {}
 
 type HardState struct {
-	Term             int64  `protobuf:"varint,1,req,name=term" json:"term"`
-	Vote             int64  `protobuf:"varint,2,req,name=vote" json:"vote"`
-	Commit           int64  `protobuf:"varint,3,req,name=commit" json:"commit"`
+	Term             uint64 `protobuf:"varint,1,req,name=term" json:"term"`
+	Vote             uint64 `protobuf:"varint,2,req,name=vote" json:"vote"`
+	Commit           uint64 `protobuf:"varint,3,req,name=commit" json:"commit"`
 	XXX_unrecognized []byte `json:"-"`
 }
 
@@ -162,9 +162,9 @@ func (m *HardState) String() string { return proto.CompactTextString(m) }
 func (*HardState) ProtoMessage()    {}
 
 type ConfChange struct {
-	ID               int64          `protobuf:"varint,1,req" json:"ID"`
+	ID               uint64         `protobuf:"varint,1,req" json:"ID"`
 	Type             ConfChangeType `protobuf:"varint,2,req,enum=raftpb.ConfChangeType" json:"Type"`
-	NodeID           int64          `protobuf:"varint,3,req" json:"NodeID"`
+	NodeID           uint64         `protobuf:"varint,3,req" json:"NodeID"`
 	Context          []byte         `protobuf:"bytes,4,opt" json:"Context"`
 	XXX_unrecognized []byte         `json:"-"`
 }
@@ -206,7 +206,7 @@ func (m *Info) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.ID |= (int64(b) & 0x7F) << shift
+				m.ID |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -278,7 +278,7 @@ func (m *Entry) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Term |= (int64(b) & 0x7F) << shift
+				m.Term |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -293,7 +293,7 @@ func (m *Entry) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Index |= (int64(b) & 0x7F) << shift
+				m.Index |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -388,14 +388,14 @@ func (m *Snapshot) Unmarshal(data []byte) error {
 			if wireType != 0 {
 				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
 			}
-			var v int64
+			var v uint64
 			for shift := uint(0); ; shift += 7 {
 				if index >= l {
 					return io.ErrUnexpectedEOF
 				}
 				b := data[index]
 				index++
-				v |= (int64(b) & 0x7F) << shift
+				v |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -411,7 +411,7 @@ func (m *Snapshot) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Index |= (int64(b) & 0x7F) << shift
+				m.Index |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -426,7 +426,7 @@ func (m *Snapshot) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Term |= (int64(b) & 0x7F) << shift
+				m.Term |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -435,14 +435,14 @@ func (m *Snapshot) Unmarshal(data []byte) error {
 			if wireType != 0 {
 				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
 			}
-			var v int64
+			var v uint64
 			for shift := uint(0); ; shift += 7 {
 				if index >= l {
 					return io.ErrUnexpectedEOF
 				}
 				b := data[index]
 				index++
-				v |= (int64(b) & 0x7F) << shift
+				v |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -500,7 +500,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Type |= (int64(b) & 0x7F) << shift
+				m.Type |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -515,7 +515,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.To |= (int64(b) & 0x7F) << shift
+				m.To |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -530,7 +530,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.From |= (int64(b) & 0x7F) << shift
+				m.From |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -545,7 +545,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Term |= (int64(b) & 0x7F) << shift
+				m.Term |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -560,7 +560,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.LogTerm |= (int64(b) & 0x7F) << shift
+				m.LogTerm |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -575,7 +575,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Index |= (int64(b) & 0x7F) << shift
+				m.Index |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -613,7 +613,7 @@ func (m *Message) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Commit |= (int64(b) & 0x7F) << shift
+				m.Commit |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -711,7 +711,7 @@ func (m *HardState) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Term |= (int64(b) & 0x7F) << shift
+				m.Term |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -726,7 +726,7 @@ func (m *HardState) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Vote |= (int64(b) & 0x7F) << shift
+				m.Vote |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -741,7 +741,7 @@ func (m *HardState) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.Commit |= (int64(b) & 0x7F) << shift
+				m.Commit |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -798,7 +798,7 @@ func (m *ConfChange) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.ID |= (int64(b) & 0x7F) << shift
+				m.ID |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -828,7 +828,7 @@ func (m *ConfChange) Unmarshal(data []byte) error {
 				}
 				b := data[index]
 				index++
-				m.NodeID |= (int64(b) & 0x7F) << shift
+				m.NodeID |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}

+ 26 - 26
raft/raftpb/raft.proto

@@ -9,7 +9,7 @@ option (gogoproto.goproto_getters_all) = false;
 option (gogoproto.goproto_enum_prefix_all) = false;
 
 message Info {
-	required int64 ID   = 1 [(gogoproto.nullable) = false];
+	required uint64 ID   = 1 [(gogoproto.nullable) = false];
 }
 
 enum EntryType {
@@ -18,37 +18,37 @@ enum EntryType {
 }
 
 message Entry {
-	required EntryType Type  = 1 [(gogoproto.nullable) = false];
-	required int64     Term  = 2 [(gogoproto.nullable) = false];
-	required int64     Index = 3 [(gogoproto.nullable) = false];
-	optional bytes     Data  = 4 [(gogoproto.nullable) = false];
+	required EntryType  Type  = 1 [(gogoproto.nullable) = false];
+	required uint64     Term  = 2 [(gogoproto.nullable) = false];
+	required uint64     Index = 3 [(gogoproto.nullable) = false];
+	optional bytes      Data  = 4 [(gogoproto.nullable) = false];
 }
 
 message Snapshot {
 	required bytes data          = 1 [(gogoproto.nullable) = false];
-	repeated int64 nodes         = 2 [(gogoproto.nullable) = false];
-	required int64 index         = 3 [(gogoproto.nullable) = false];
-	required int64 term          = 4 [(gogoproto.nullable) = false];
-	repeated int64 removed_nodes = 5 [(gogoproto.nullable) = false];
+	repeated uint64 nodes         = 2 [(gogoproto.nullable) = false];
+	required uint64 index         = 3 [(gogoproto.nullable) = false];
+	required uint64 term          = 4 [(gogoproto.nullable) = false];
+	repeated uint64 removed_nodes = 5 [(gogoproto.nullable) = false];
 }
 
 message Message {
-	required int64 type        = 1  [(gogoproto.nullable) = false];
-	required int64 to          = 2  [(gogoproto.nullable) = false];
-	required int64 from        = 3  [(gogoproto.nullable) = false];
-	required int64 term        = 4  [(gogoproto.nullable) = false];
-	required int64 logTerm     = 5  [(gogoproto.nullable) = false];
-	required int64 index       = 6  [(gogoproto.nullable) = false];
-	repeated Entry entries     = 7  [(gogoproto.nullable) = false];
-	required int64 commit      = 8  [(gogoproto.nullable) = false];
-	required Snapshot snapshot = 9  [(gogoproto.nullable) = false];
-	required bool  reject      = 10 [(gogoproto.nullable) = false];
+	required uint64 type        = 1  [(gogoproto.nullable) = false];
+	required uint64 to          = 2  [(gogoproto.nullable) = false];
+	required uint64 from        = 3  [(gogoproto.nullable) = false];
+	required uint64 term        = 4  [(gogoproto.nullable) = false];
+	required uint64 logTerm     = 5  [(gogoproto.nullable) = false];
+	required uint64 index       = 6  [(gogoproto.nullable) = false];
+	repeated Entry entries      = 7  [(gogoproto.nullable) = false];
+	required uint64 commit      = 8  [(gogoproto.nullable) = false];
+	required Snapshot snapshot  = 9  [(gogoproto.nullable) = false];
+	required bool  reject       = 10 [(gogoproto.nullable) = false];
 }
 
 message HardState {
-	required int64 term   = 1 [(gogoproto.nullable) = false];
-	required int64 vote   = 2 [(gogoproto.nullable) = false];
-	required int64 commit = 3 [(gogoproto.nullable) = false];
+	required uint64 term   = 1 [(gogoproto.nullable) = false];
+	required uint64 vote   = 2 [(gogoproto.nullable) = false];
+	required uint64 commit = 3 [(gogoproto.nullable) = false];
 }
 
 enum ConfChangeType {
@@ -57,8 +57,8 @@ enum ConfChangeType {
 }
 
 message ConfChange {
-	required int64          ID      = 1 [(gogoproto.nullable) = false];
-	required ConfChangeType Type    = 2 [(gogoproto.nullable) = false];
-	required int64          NodeID  = 3 [(gogoproto.nullable) = false];
-	optional bytes          Context = 4 [(gogoproto.nullable) = false];
+	required uint64          ID      = 1 [(gogoproto.nullable) = false];
+	required ConfChangeType  Type    = 2 [(gogoproto.nullable) = false];
+	required uint64          NodeID  = 3 [(gogoproto.nullable) = false];
+	optional bytes           Context = 4 [(gogoproto.nullable) = false];
 }