Skip to content

Add signature replay, fix single-node startup, change log statements#10

Open
tschuyebuhl wants to merge 3 commits intomasterfrom
fix-bootstrap
Open

Add signature replay, fix single-node startup, change log statements#10
tschuyebuhl wants to merge 3 commits intomasterfrom
fix-bootstrap

Conversation

@tschuyebuhl
Copy link
Contributor

To simplify the leader loop, I removed the local persistence mode

Gist of the changes is:

  • in a single-node mode, use LightReady to advance the commit index. This is a quirk of the raft-rs lib, where in single-node mode, progress automatically updates quorum, and the commit changes after advance. This caused replays on Nebula restarts.
  • when handling votes, sign again votes differing only by timestamp. it is ok to re-sign such votes, and not doing so may stall a chain in extreme situations (my devnets mostly, unless we get to a future where a whole chain is on nebula)
  • event driven leader lifecycle (yay)

@tschuyebuhl tschuyebuhl requested review from DavidVentura and qezz March 6, 2026 15:46
I decided to remove it for now and will add it back later
Copy link
Contributor

@DavidVentura DavidVentura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice to see the raft events<>signer sm

In other words, a proposal should only be signed if it’s at a higher height, or a higher round for the same height. Once a proposal or vote has been signed for a given height and round, a proposal should never be signed for the same height and round.
*/
fn should_sign_proposal(state: &ConsensusData, proposal: &Proposal) -> bool {
pub fn should_sign_proposal(state: &ConsensusData, proposal: &Proposal) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why pub, feels dangerous

#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct ConsensusData {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

derive default is pretty spicy, you can forget the round attr and the Default::default() will screw you

i'd say add from_hrs or impl From, From, ... and those fill in with empty vecs

// TODO: don't connect if we are not the master; it will block the master from connecting
// and we need to close the connection on leadership loss
match rx.recv() {
Ok(RaftEvent::LeadershipChanged(from, to)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmmmmmmm feels a little bit off, but i think it's fine.
i'll see if i can come up with an idea

..Default::default()
};

let current_state = raft_node.signer_state.read().unwrap().clone();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logic should be part of the type, or check module or should_sign, etc.

then it'll be easier to consider the cases in isolation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants