mirror of
https://github.com/status-im/nim-raft.git
synced 2025-03-03 14:20:35 +00:00
Refactor. Add new stuff.
This commit is contained in:
parent
2d72da3b94
commit
d6419eb02f
11
nimble.lock
11
nimble.lock
@ -43,6 +43,17 @@
|
||||
"checksums": {
|
||||
"sha1": "f76c87707cd4e96355b8bb6ef27e7f8b0aac1e08"
|
||||
}
|
||||
},
|
||||
,
|
||||
"fsm.nim": {
|
||||
"version": "0.1.1",
|
||||
"vcsRevision": "ca6e14a5562e46805ed89593cb63bf6236939772",
|
||||
"url": "https://github.com/ba0f3/fsm.nim",
|
||||
"downloadMethod": "git",
|
||||
"dependencies": [],
|
||||
"checksums": {
|
||||
"sha1": "f76c87707cd4e96355b8bb6ef27e7f8b0aac1e08"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,5 +20,6 @@ requires "stew >= 0.1.0"
|
||||
requires "nimcrypto >= 0.5.4"
|
||||
requires "unittest2 >= 0.0.4"
|
||||
requires "chronicles >= 0.10.2"
|
||||
requires "fsm.nim >= 0.1.0"
|
||||
|
||||
# Helper functions
|
||||
|
8
raft_consensus/consensus_module.nim
Normal file
8
raft_consensus/consensus_module.nim
Normal file
@ -0,0 +1,8 @@
|
||||
# nim-raft-consesnsus
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
8
raft_consensus/log_compaction_module.nim
Normal file
8
raft_consensus/log_compaction_module.nim
Normal file
@ -0,0 +1,8 @@
|
||||
# nim-raft-consesnsus
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
8
raft_consensus/membersip_change_module.nim
Normal file
8
raft_consensus/membersip_change_module.nim
Normal file
@ -0,0 +1,8 @@
|
||||
# nim-raft-consesnsus
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
@ -6,115 +6,8 @@
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
import types
|
||||
|
||||
|
||||
# RAFT Node Public Types.
|
||||
# I guess that at some point these can be moved to a separate file called raft_consensus_types.nim for example
|
||||
type
|
||||
# RAFT Node basic definitions
|
||||
Blob* = seq[byte]
|
||||
|
||||
RAFTNodeState* = enum
|
||||
UNKNOWN = 0,
|
||||
FOLLOWER = 1,
|
||||
LEADER = 2
|
||||
|
||||
RAFTNodeId* = object # Some kind of UUID uniquely identifying every RAFT Node
|
||||
RAFTNodePeers* = seq[RAFTNodeId] # List of RAFT Node Peers IDs
|
||||
RAFTNodeTerm* = uint64 # RAFT Node Term Type
|
||||
RAFTLogIndex* = uint64 # RAFT Node Log Index Type
|
||||
|
||||
# RAFT Node basic Log definitions
|
||||
RAFTNodeLogEntry* = ref object # Abstarct RAFT Node Log entry containing opaque binary data (Blob)
|
||||
term*: RAFTNodeTerm
|
||||
data*: Blob
|
||||
|
||||
RAFTNodeLog* = ref object # Needs more elaborate definition. Probably this will be a RocksDB/MDBX/SQLite Store Wrapper etc.
|
||||
log_data*: seq[RAFTNodeLogEntry] # RAFT Node Log Data
|
||||
|
||||
# RAFT Node basic Messages definitions
|
||||
RAFTMessageId* = object # Some Kind of UUID assigned to every RAFT Node Message,
|
||||
# so it can be matched with it's coresponding response etc.
|
||||
|
||||
RAFTMessageOps* = enum
|
||||
REQUEST_VOTE = 0,
|
||||
APPEND_LOG_ENTRY = 1,
|
||||
INSTALL_SNAPSHOT = 2 # For dynamic adding of new RAFT Nodes
|
||||
|
||||
RAFTMessagePayloadChecksum* = object # Checksum probably will be a SHA3 hash not sure about this at this point
|
||||
RAFTMessagePayload* = ref object
|
||||
data*: RAFTNodeLogEntry
|
||||
checksum*: RAFTMessagePayloadChecksum
|
||||
|
||||
RAFTMessageBase* = ref object of RootObj # Base Type for RAFT Node Messages
|
||||
msg_id*: RAFTMessageId # Message UUID
|
||||
sender_id*: RAFTNodeId # Sender RAFT Node ID
|
||||
sender_term*: RAFTNodeTerm # Sender RAFT Node Term
|
||||
peers*: RAFTNodePeers # List of RAFT Node IDs, which should receive this message
|
||||
|
||||
RAFTMessage* = ref object of RAFTMessageBase
|
||||
op*: RAFTMessageOps # Message Op - Ask For Votes, Append Entry(ies) or Install Snapshot
|
||||
payload*: seq[RAFTMessagePayload] # Message Payload(s) - e.g. log entry(ies) etc. Will be empty for a Heart-Beat # Heart-Beat will be a message with Append Entry(ies) Op and empty payload
|
||||
|
||||
RAFTMessageResponse* = ref object of RAFTMessageBase
|
||||
success*: bool # Indicates success/failure
|
||||
|
||||
RAFTMessageSendCallback* = proc (raft_message: RAFTMessageBase) {.nimcall, gcsafe.} # Callback for Sending RAFT Node Messages
|
||||
# out of this RAFT Node. Can be used for broadcasting
|
||||
# (a Heart-Beat for example)
|
||||
# RAFT Node Client Request/Response basic definitions
|
||||
RAFTNodeClientRequestOps = enum
|
||||
REQUEST_STATE = 0,
|
||||
APPEND_NEW_ENTRY = 1
|
||||
|
||||
RAFTNodeClientRequest* = ref object
|
||||
op*: RAFTNodeClientRequestOps
|
||||
payload*: RAFTNodeLogEntry
|
||||
|
||||
RAFTNodeClientResponse* = ref object
|
||||
success*: bool # Indicate succcess
|
||||
raft_node_redirect_id*: RAFTNodeId # RAFT Node ID to redirect the request to in case of failure
|
||||
|
||||
# RAFT Node State Machine basic definitions
|
||||
RAFTNodeStateMachineState* = object # State Machine State
|
||||
RAFTNodeStateMachine* = ref object # Some probably opaque State Machine Impelementation to be used by the RAFT Node
|
||||
# providing at minimum operations for initialization, querying the current state
|
||||
# and RAFTNodeLogEntry application
|
||||
state: RAFTNodeStateMachineState
|
||||
|
||||
# RAFT Node Persistent Storage basic definition
|
||||
RAFTNodePersistentStorage* = ref object # Should be some kind of Persistent Transactional Store Wrapper
|
||||
|
||||
# RAFT Node Object definitions
|
||||
RAFTNode* = object
|
||||
# Timers definitions goes here
|
||||
# ...
|
||||
|
||||
msg_send_callback: RAFTMessageSendCallback
|
||||
persistent_storage: RAFTNodePersistentStorage
|
||||
|
||||
# Persistent state
|
||||
id: RAFTNodeId # This RAFT Node ID
|
||||
state: RAFTNodeState # This RAFT Node State
|
||||
current_term: RAFTNodeTerm # Latest term this RAFT Node has seen (initialized to 0 on first boot, increases monotonically)
|
||||
log: RAFTNodeLog # This RAFT Node Log
|
||||
voted_for: RAFTNodeId # Candidate RAFTNodeId that received vote in current term (or nil/zero if none)
|
||||
peers: RAFTNodePeers # This RAFT Node Peers IDs. I am not sure if this must be persistent or volatile but making it persistent
|
||||
# makes sense for the moment
|
||||
state_machine: RAFTNodeStateMachine # Not sure for now putting it here. I assume that persisting the State Machine's state is enough
|
||||
# to consider it 'persisted'
|
||||
|
||||
# Volatile state
|
||||
commit_index: RAFTLogIndex # Index of highest log entry known to be committed (initialized to 0, increases monotonically)
|
||||
last_applied: RAFTLogIndex # Index of highest log entry applied to state machine (initialized to 0, increases monotonically)
|
||||
current_leader_id: RAFTNodeId # Current RAFT Node Leader ID (used to redirect Client Requests in case this RAFT Node is not the leader)
|
||||
|
||||
# Volatile state on leaders
|
||||
next_index: seq[RAFTLogIndex] # For each peer RAFT Node, index of the next log entry to send to that Node
|
||||
# (initialized to leader last log index + 1)
|
||||
match_index: seq[RAFTLogIndex] # For each peer RAFT Node, index of highest log entry known to be replicated on Node
|
||||
# (initialized to 0, increases monotonically)
|
||||
|
||||
# RAFT Node Public API procedures / functions
|
||||
proc RAFTNodeCreateNew*(id: RAFTNodeId, peers: RAFTNodePeers, state_machine: RAFTNodeStateMachine, # Create New RAFT Node
|
||||
log: RAFTNodeLog, persistent_storage: RAFTNodePersistentStorage,
|
||||
|
118
raft_consensus/types.nim
Normal file
118
raft_consensus/types.nim
Normal file
@ -0,0 +1,118 @@
|
||||
# RAFT Node Public Types.
|
||||
# I guess that at some point these can be moved to a separate file called raft_consensus_types.nim for example
|
||||
import fsm
|
||||
|
||||
type
|
||||
# RAFT Node basic definitions
|
||||
Blob* = seq[byte]
|
||||
|
||||
RAFTNodeState* = enum
|
||||
UNKNOWN = 0,
|
||||
FOLLOWER = 1,
|
||||
LEADER = 2
|
||||
|
||||
RAFTNodeId* = object # Some kind of UUID uniquely identifying every RAFT Node
|
||||
RAFTNodePeers* = seq[RAFTNodeId] # List of RAFT Node Peers IDs
|
||||
RAFTNodeTerm* = uint64 # RAFT Node Term Type
|
||||
RAFTLogIndex* = uint64 # RAFT Node Log Index Type
|
||||
|
||||
# RAFT Node basic Log definitions
|
||||
RAFTNodeLogEntry* = ref object # Abstarct RAFT Node Log entry containing opaque binary data (Blob)
|
||||
term*: RAFTNodeTerm
|
||||
data*: Blob
|
||||
|
||||
RAFTNodeLog* = ref object # Needs more elaborate definition. Probably this will be a RocksDB/MDBX/SQLite Store Wrapper etc.
|
||||
log_data*: seq[RAFTNodeLogEntry] # RAFT Node Log Data
|
||||
|
||||
# RAFT Node basic Messages definitions
|
||||
RAFTMessageId* = object # Some Kind of UUID assigned to every RAFT Node Message,
|
||||
# so it can be matched with it's coresponding response etc.
|
||||
|
||||
RAFTMessageOps* = enum
|
||||
REQUEST_VOTE = 0,
|
||||
APPEND_LOG_ENTRY = 1,
|
||||
INSTALL_SNAPSHOT = 2 # For dynamic adding of new RAFT Nodes
|
||||
|
||||
RAFTMessagePayloadChecksum* = object # Checksum probably will be a SHA3 hash not sure about this at this point
|
||||
RAFTMessagePayload* = ref object
|
||||
data*: RAFTNodeLogEntry
|
||||
checksum*: RAFTMessagePayloadChecksum
|
||||
|
||||
RAFTMessageBase* = ref object of RootObj # Base Type for RAFT Node Messages
|
||||
msg_id*: RAFTMessageId # Message UUID
|
||||
sender_id*: RAFTNodeId # Sender RAFT Node ID
|
||||
sender_term*: RAFTNodeTerm # Sender RAFT Node Term
|
||||
peers*: RAFTNodePeers # List of RAFT Node IDs, which should receive this message
|
||||
|
||||
RAFTMessage* = ref object of RAFTMessageBase
|
||||
op*: RAFTMessageOps # Message Op - Ask For Votes, Append Entry(ies) or Install Snapshot
|
||||
payload*: seq[RAFTMessagePayload] # Message Payload(s) - e.g. log entry(ies) etc. Will be empty for a Heart-Beat # Heart-Beat will be a message with Append Entry(ies) Op and empty payload
|
||||
|
||||
RAFTMessageResponse* = ref object of RAFTMessageBase
|
||||
success*: bool # Indicates success/failure
|
||||
|
||||
RAFTMessageSendCallback* = proc (raft_message: RAFTMessageBase) {.nimcall, gcsafe.} # Callback for Sending RAFT Node Messages
|
||||
# out of this RAFT Node. Can be used for broadcasting
|
||||
# (a Heart-Beat for example)
|
||||
# RAFT Node Client Request/Response basic definitions
|
||||
RAFTNodeClientRequestOps = enum
|
||||
REQUEST_STATE = 0,
|
||||
APPEND_NEW_ENTRY = 1
|
||||
|
||||
RAFTNodeClientRequest* = ref object
|
||||
op*: RAFTNodeClientRequestOps
|
||||
payload*: RAFTNodeLogEntry
|
||||
|
||||
RAFTNodeClientResponse* = ref object
|
||||
success*: bool # Indicate succcess
|
||||
raft_node_redirect_id*: RAFTNodeId # RAFT Node ID to redirect the request to in case of failure
|
||||
|
||||
# RAFT Node State Machine basic definitions
|
||||
RAFTNodeStateMachineState* = object # State Machine State
|
||||
RAFTNodeStateMachine* = ref object # Some probably opaque State Machine Impelementation to be used by the RAFT Node
|
||||
# providing at minimum operations for initialization, querying the current state
|
||||
# and RAFTNodeLogEntry application
|
||||
state: RAFTNodeStateMachineState
|
||||
|
||||
# RAFT Node Persistent Storage basic definition
|
||||
RAFTNodePersistentStorage* = ref object # Should be some kind of Persistent Transactional Store Wrapper
|
||||
|
||||
# RAFT Node Object definitions
|
||||
RAFTNode* = object
|
||||
# Timers definitions goes here
|
||||
# ...
|
||||
|
||||
msg_send_callback: RAFTMessageSendCallback
|
||||
persistent_storage: RAFTNodePersistentStorage
|
||||
|
||||
# Persistent state
|
||||
id: RAFTNodeId # This RAFT Node ID
|
||||
state: RAFTNodeState # This RAFT Node State
|
||||
current_term: RAFTNodeTerm # Latest term this RAFT Node has seen (initialized to 0 on first boot, increases monotonically)
|
||||
log: RAFTNodeLog # This RAFT Node Log
|
||||
voted_for: RAFTNodeId # Candidate RAFTNodeId that received vote in current term (or nil/zero if none)
|
||||
peers: RAFTNodePeers # This RAFT Node Peers IDs. I am not sure if this must be persistent or volatile but making it persistent
|
||||
# makes sense for the moment
|
||||
state_machine: RAFTNodeStateMachine # Not sure for now putting it here. I assume that persisting the State Machine's state is enough
|
||||
# to consider it 'persisted'
|
||||
|
||||
# Volatile state
|
||||
commit_index: RAFTLogIndex # Index of highest log entry known to be committed (initialized to 0, increases monotonically)
|
||||
last_applied: RAFTLogIndex # Index of highest log entry applied to state machine (initialized to 0, increases monotonically)
|
||||
current_leader_id: RAFTNodeId # Current RAFT Node Leader ID (used to redirect Client Requests in case this RAFT Node is not the leader)
|
||||
|
||||
# Volatile state on leaders
|
||||
next_index: seq[RAFTLogIndex] # For each peer RAFT Node, index of the next log entry to send to that Node
|
||||
# (initialized to leader last log index + 1)
|
||||
match_index: seq[RAFTLogIndex] # For each peer RAFT Node, index of highest log entry known to be replicated on Node
|
||||
# (initialized to 0, increases monotonically)
|
||||
|
||||
RAFTConsensusModule* = ref object
|
||||
state_transitions_fsm: fsm # I plan to use nim.fsm https://github.com/ba0f3/fsm.nim
|
||||
raft_node: RAFTNode
|
||||
|
||||
RAFTLogCompactioModule* = ref object
|
||||
raft_node: RAFTNode
|
||||
|
||||
RAFTMembershipChangeModule* = ref object
|
||||
raft_node: RAFTNode
|
Loading…
x
Reference in New Issue
Block a user