- Notifications
You must be signed in to change notification settings - Fork 22
feat: initial LeoisFetch protocol #1209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds a new LeiosFetch node-to-node protocol (client, server, CBOR messages, config/callbacks) and wires it into Connection lifecycle; also adjusts an existing LeiosNotify protocol identifier and its Done state numeric ID. Changes
Sequence Diagram(s)sequenceDiagram participant Client participant ClientProtocol as Client Protocol participant ServerProtocol as Server Protocol participant ServerHandler as Server Handler rect rgb(220, 235, 255) note over Client,ServerHandler: Single-item request/response (Block) Client->>ClientProtocol: Send MsgBlockRequest(slot, hash) ClientProtocol->>ServerProtocol: transport message ServerProtocol->>ServerHandler: messageHandler(MsgBlockRequest) ServerHandler->>ServerHandler: invoke BlockRequestFunc(ctx, slot, hash) ServerHandler-->>ServerProtocol: send MsgBlock ServerProtocol-->>ClientProtocol: deliver MsgBlock ClientProtocol->>Client: enqueue MsgBlock (client channel) end sequenceDiagram participant Client participant ClientProtocol as Client Protocol participant ServerProtocol as Server Protocol participant ServerHandler as Server Handler rect rgb(235, 255, 230) note over Client,ServerHandler: Multi-message BlockRange flow Client->>ClientProtocol: Send MsgBlockRangeRequest(start,end) ClientProtocol->>ServerProtocol: transport message ServerProtocol->>ServerHandler: messageHandler(MsgBlockRangeRequest) ServerHandler->>ServerHandler: invoke BlockRangeRequestFunc(ctx, start, end) loop multiple blocks ServerHandler-->>ServerProtocol: send MsgNextBlockAndTxsInRange ServerProtocol-->>ClientProtocol: deliver MsgNextBlockAndTxsInRange ClientProtocol->>Client: enqueue (range channel) end ServerHandler-->>ServerProtocol: send MsgLastBlockAndTxsInRange ServerProtocol-->>ClientProtocol: deliver MsgLastBlockAndTxsInRange (completion) ClientProtocol->>Client: finalize BlockRangeRequest result end Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
protocol/leiosfetch/client.go (1)
25-35: Document single-flight expectations or add serializationMultiple concurrent requests of the same kind will race on shared result channels (e.g., two BlockRequests). Either document that the client is single‑flight per request type or serialize internally (mutex/queue).
protocol/leiosfetch/server.go (1)
194-206: Restarting protocol inside message handler may raceCalling Stop/initProtocol/Start synchronously from within the handler can deadlock or fight with the receiver loop. Prefer deferring restart in a goroutine.
- // Restart protocol - s.Stop() - s.initProtocol() - s.Start() + // Restart protocol asynchronously to avoid handler/loop reentrancy + go func() { + _ = s.Stop() + s.initProtocol() + s.Start() + }()protocol/leiosfetch/leiosfetch.go (1)
115-121: Minor: clarify Timeout scopeTimeout appears to be applied only on the client (via state map overrides). Add a short comment to avoid confusion for server users.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
connection.go(6 hunks)protocol/leiosfetch/client.go(1 hunks)protocol/leiosfetch/leiosfetch.go(1 hunks)protocol/leiosfetch/messages.go(1 hunks)protocol/leiosfetch/server.go(1 hunks)protocol/leiosnotify/leiosnotify.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
connection.go (3)
protocol/leiosfetch/leiosfetch.go (3)
LeiosFetch(110-113)Config(115-121)New(138-144)protocol/leiosfetch/client.go (1)
Client(25-35)protocol/leiosfetch/server.go (1)
Server(24-29)
protocol/leiosfetch/server.go (4)
protocol/protocol.go (6)
Protocol(39-54)ProtocolOptions(93-102)ProtocolConfig(57-71)ProtocolRoleServer(89-89)MessageHandlerFunc(110-110)MessageFromCborFunc(113-113)protocol/leiosfetch/leiosfetch.go (10)
Config(115-121)CallbackContext(124-128)ProtocolName(26-26)ProtocolId(27-27)StateMap(39-108)New(138-144)BlockRequestFunc(132-132)BlockTxsRequestFunc(133-133)VotesRequestFunc(134-134)BlockRangeRequestFunc(135-135)protocol/leiosfetch/messages.go (10)
NewMsgFromCbor(41-73)MessageTypeBlockRequest(29-29)MessageTypeBlockTxsRequest(31-31)MessageTypeVotesRequest(33-33)MessageTypeBlockRangeRequest(35-35)MessageTypeDone(38-38)MsgBlockRequest(75-79)MsgBlockTxsRequest(107-112)MsgVotesRequest(141-144)MsgBlockRangeRequest(177-181)protocol/message.go (1)
Message(18-22)
protocol/leiosfetch/client.go (5)
protocol/protocol.go (6)
Protocol(39-54)ProtocolOptions(93-102)ProtocolConfig(57-71)ProtocolRoleClient(88-88)MessageHandlerFunc(110-110)MessageFromCborFunc(113-113)protocol/leiosfetch/leiosfetch.go (12)
Config(115-121)CallbackContext(124-128)NewConfig(148-157)StateMap(39-108)StateBlock(32-32)StateBlockTxs(33-33)StateVotes(34-34)StateBlockRange(35-35)ProtocolName(26-26)ProtocolId(27-27)StateIdle(31-31)New(138-144)protocol/leiosfetch/messages.go (13)
NewMsgFromCbor(41-73)NewMsgDone(232-239)NewMsgBlockRequest(81-90)NewMsgBlockTxsRequest(114-124)MsgVotesRequestVoteId(146-150)NewMsgVotesRequest(152-160)NewMsgBlockRangeRequest(183-192)MsgLastBlockAndTxsInRange(211-215)MessageTypeBlock(30-30)MessageTypeBlockTxs(32-32)MessageTypeVotes(34-34)MessageTypeNextBlockAndTxsInRange(37-37)MessageTypeLastBlockAndTxsInRange(36-36)protocol/error.go (1)
ErrProtocolShuttingDown(19-19)protocol/common/types.go (1)
Point(23-28)
protocol/leiosnotify/leiosnotify.go (1)
protocol/state.go (1)
NewState(38-43)
protocol/leiosfetch/messages.go (5)
protocol/message.go (2)
Message(18-22)MessageBase(25-30)cbor/decode.go (1)
Decode(29-44)protocol/leiosfetch/leiosfetch.go (1)
ProtocolName(26-26)cbor/cbor.go (2)
RawMessage(36-36)StructAsArray(45-48)protocol/common/types.go (1)
Point(23-28)
protocol/leiosfetch/leiosfetch.go (7)
protocol/state.go (6)
NewState(38-43)StateMapEntry(62-66)AgencyClient(27-27)StateTransition(51-55)AgencyServer(28-28)AgencyNone(26-26)protocol/leiosfetch/messages.go (11)
MessageTypeBlockRequest(29-29)MessageTypeBlockTxsRequest(31-31)MessageTypeVotesRequest(33-33)MessageTypeBlockRangeRequest(35-35)MessageTypeDone(38-38)MessageTypeBlock(30-30)MessageTypeBlockTxs(32-32)MessageTypeVotes(34-34)MessageTypeNextBlockAndTxsInRange(37-37)MessageTypeLastBlockAndTxsInRange(36-36)MsgVotesRequestVoteId(146-150)protocol/leiosfetch/client.go (2)
Client(25-35)NewClient(37-87)protocol/leiosfetch/server.go (2)
Server(24-29)NewServer(31-43)connection.go (2)
ConnectionId(56-56)New(133-135)protocol/common/types.go (1)
Point(23-28)protocol/protocol.go (1)
ProtocolOptions(93-102)
🔇 Additional comments (8)
protocol/leiosnotify/leiosnotify.go (2)
32-32: Sequential state IDs improve consistency.The state ID change makes the state sequence sequential (1, 2, 3 instead of 1, 2, 4), which improves maintainability. However, this is a breaking change if state IDs are persisted or referenced by external systems.
If this protocol was previously deployed, please verify that no persistent state references the old state ID 4.
26-26: Protocol ID and state ID assignments are correct and intentional.The changes from ProtocolId 998→18 and StateDone 4→3 represent the official assignment of protocol and state identifiers to new Leios protocols. The previous code explicitly marked 998 as a dummy value awaiting replacement. Both changes are consistent with the codebase design:
- Protocol IDs 18 and 19 follow the existing numbering scheme for protocol assignments
- State IDs are now sequential (1, 2, 3) matching the pattern in LeiosFetch
- These are new protocols being formalized, not modifications to existing ones
- No backward compatibility concerns exist—these protocols are not yet deployed to production nodes
No migration plan is needed, and all protocol ID references have been properly updated throughout the codebase.
connection.go (3)
89-103: Wiring fields look goodAdding leiosFetch and leiosFetchConfig matches existing mini‑protocol patterns. No concerns.
215-218: Public accessor LGTMLeiosFetch() mirrors other accessors and is idiomatic.
416-444: ProtocolId 19 is unique and properly defined; verify peer compatibility before unconditional startup.Verification confirms:
- ProtocolId 19 is unique (no other protocol reuses it)
- LeiosFetch is created and started unconditionally without nil checks or feature flags, unlike keepAlive (
sendKeepAlivesboolean) and peerSharing (nil check)- LeiosNotify follows the same unconditional pattern
The risk is that peers may not support the leios-fetch protocol. If all target peers support it, this is acceptable; otherwise, consider adding a feature-gate flag or version negotiation similar to keepAlive. Only you can verify peer compatibility at runtime or through protocol documentation.
protocol/leiosfetch/client.go (1)
89-107: Shutdown cleanup timingClosing result channels on <-DoneChan is fine assuming Protocol guarantees no further handler invocations afterward. Please confirm Protocol.Stop() semantics prevent sends after Done to avoid “send on closed channel” panics.
protocol/leiosfetch/messages.go (1)
27-39: Message type IDs marked “dummy”These constants are labeled temporary. Please reconcile with the spec and update before releasing to avoid wire incompatibility.
protocol/leiosfetch/leiosfetch.go (1)
25-29: ProtocolId 19 collision check passedNo collision detected. ID 19 is unique; existing protocols use IDs: 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18.
| func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) { | ||
| var ret protocol.Message | ||
| switch msgType { | ||
| case MessageTypeBlockRequest: | ||
| ret = &MsgBlockRequest{} | ||
| case MessageTypeBlock: | ||
| ret = &MsgBlock{} | ||
| case MessageTypeBlockTxsRequest: | ||
| ret = &MsgBlockTxsRequest{} | ||
| case MessageTypeBlockTxs: | ||
| ret = &MsgBlockTxs{} | ||
| case MessageTypeVotesRequest: | ||
| ret = &MsgVotesRequest{} | ||
| case MessageTypeVotes: | ||
| ret = &MsgVotes{} | ||
| case MessageTypeBlockRangeRequest: | ||
| ret = &MsgBlockRangeRequest{} | ||
| case MessageTypeLastBlockAndTxsInRange: | ||
| ret = &MsgLastBlockAndTxsInRange{} | ||
| case MessageTypeNextBlockAndTxsInRange: | ||
| ret = &MsgNextBlockAndTxsInRange{} | ||
| case MessageTypeDone: | ||
| ret = &MsgDone{} | ||
| } | ||
| if _, err := cbor.Decode(data, ret); err != nil { | ||
| return nil, fmt.Errorf("%s: decode error: %w", ProtocolName, err) | ||
| } | ||
| if ret != nil { | ||
| // Store the raw message CBOR | ||
| ret.SetCbor(data) | ||
| } | ||
| return ret, nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard unknown message types before decoding
If msgType isn’t recognized, ret is nil and cbor.Decode(nil, …) risks a panic or undefined behavior. Return a clear error early.
func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) { var ret protocol.Message switch msgType { // cases... } + if ret == nil { + return nil, fmt.Errorf("%s: unknown message type: %d", ProtocolName, msgType) + } if _, err := cbor.Decode(data, ret); err != nil { return nil, fmt.Errorf("%s: decode error: %w", ProtocolName, err) } if ret != nil { // Store the raw message CBOR ret.SetCbor(data) } return ret, nil }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) { | |
| var ret protocol.Message | |
| switch msgType { | |
| case MessageTypeBlockRequest: | |
| ret = &MsgBlockRequest{} | |
| case MessageTypeBlock: | |
| ret = &MsgBlock{} | |
| case MessageTypeBlockTxsRequest: | |
| ret = &MsgBlockTxsRequest{} | |
| case MessageTypeBlockTxs: | |
| ret = &MsgBlockTxs{} | |
| case MessageTypeVotesRequest: | |
| ret = &MsgVotesRequest{} | |
| case MessageTypeVotes: | |
| ret = &MsgVotes{} | |
| case MessageTypeBlockRangeRequest: | |
| ret = &MsgBlockRangeRequest{} | |
| case MessageTypeLastBlockAndTxsInRange: | |
| ret = &MsgLastBlockAndTxsInRange{} | |
| case MessageTypeNextBlockAndTxsInRange: | |
| ret = &MsgNextBlockAndTxsInRange{} | |
| case MessageTypeDone: | |
| ret = &MsgDone{} | |
| } | |
| if _, err := cbor.Decode(data, ret); err != nil { | |
| return nil, fmt.Errorf("%s: decode error: %w", ProtocolName, err) | |
| } | |
| if ret != nil { | |
| // Store the raw message CBOR | |
| ret.SetCbor(data) | |
| } | |
| return ret, nil | |
| } | |
| func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) { | |
| var ret protocol.Message | |
| switch msgType { | |
| case MessageTypeBlockRequest: | |
| ret = &MsgBlockRequest{} | |
| case MessageTypeBlock: | |
| ret = &MsgBlock{} | |
| case MessageTypeBlockTxsRequest: | |
| ret = &MsgBlockTxsRequest{} | |
| case MessageTypeBlockTxs: | |
| ret = &MsgBlockTxs{} | |
| case MessageTypeVotesRequest: | |
| ret = &MsgVotesRequest{} | |
| case MessageTypeVotes: | |
| ret = &MsgVotes{} | |
| case MessageTypeBlockRangeRequest: | |
| ret = &MsgBlockRangeRequest{} | |
| case MessageTypeLastBlockAndTxsInRange: | |
| ret = &MsgLastBlockAndTxsInRange{} | |
| case MessageTypeNextBlockAndTxsInRange: | |
| ret = &MsgNextBlockAndTxsInRange{} | |
| case MessageTypeDone: | |
| ret = &MsgDone{} | |
| } | |
| if ret == nil { | |
| return nil, fmt.Errorf("%s: unknown message type: %d", ProtocolName, msgType) | |
| } | |
| if _, err := cbor.Decode(data, ret); err != nil { | |
| return nil, fmt.Errorf("%s: decode error: %w", ProtocolName, err) | |
| } | |
| if ret != nil { | |
| // Store the raw message CBOR | |
| ret.SetCbor(data) | |
| } | |
| return ret, nil | |
| } |
🤖 Prompt for AI Agents
In protocol/leiosfetch/messages.go around lines 41 to 73, the function may call cbor.Decode with ret == nil when msgType is unrecognized; add a guard to return a clear error before decoding (e.g., after the switch, if ret == nil return fmt.Errorf("%s: unknown message type %d", ProtocolName, msgType)), so decoding is only attempted for known types and avoid calling ret.SetCbor when ret is nil. Signed-off-by: Aurora Gaffney <aurora@blinklabs.io>
6ba18b7 to 7153902 Compare There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
protocol/leiosfetch/messages.go (1)
41-73: Guard unknown message types before decoding (prevents nil decode panic)
If msgType is unrecognized, ret is nil and cbor.Decode will panic/err. Return early.Apply this diff:
func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) { var ret protocol.Message switch msgType { // cases... } + if ret == nil { + return nil, fmt.Errorf("%s: unknown message type: %d", ProtocolName, msgType) + } if _, err := cbor.Decode(data, ret); err != nil { return nil, fmt.Errorf("%s: decode error: %w", ProtocolName, err) } if ret != nil { // Store the raw message CBOR ret.SetCbor(data) } return ret, nil }
🧹 Nitpick comments (5)
protocol/leiosfetch/leiosfetch.go (1)
138-144: Lifecycle: constructing both Client and Server—confirm only one starts per connection
New() builds both sides sharing the same muxer/ProtocolId. Verify the connection bootstrap never starts both simultaneously for a single stream to avoid contention. If there’s any risk, expose role‑specific constructors or guard Starts.protocol/leiosfetch/messages.go (2)
27-39: Finalize wire message IDs before merge
Comment says these are “dummy” IDs. Please lock them to the LEIOS wire spec to avoid breaking interop, and remove the note.
97-105: Deep‑clone raw payloads to avoid aliasing after return
Several constructors copy only the slice header (slices.Clone) but not each []byte. Use bytes.Clone per element for cbor.RawMessage and nested []byte (VoteIssuerId).func NewMsgBlock(block cbor.RawMessage) *MsgBlock { m := &MsgBlock{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeBlock, }, - BlockRaw: block, + BlockRaw: bytes.Clone(block), } return m } func NewMsgBlockTxs(txs []cbor.RawMessage) *MsgBlockTxs { - m := &MsgBlockTxs{ + // deep-clone each raw message + cloned := make([]cbor.RawMessage, len(txs)) + for i := range txs { + cloned[i] = bytes.Clone(txs[i]) + } + m := &MsgBlockTxs{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeBlockTxs, }, - TxsRaw: slices.Clone(txs), + TxsRaw: cloned, } return m } func NewMsgVotes(votes []cbor.RawMessage) *MsgVotes { - m := &MsgVotes{ + cloned := make([]cbor.RawMessage, len(votes)) + for i := range votes { + cloned[i] = bytes.Clone(votes[i]) + } + m := &MsgVotes{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeVotes, }, - VotesRaw: slices.Clone(votes), + VotesRaw: cloned, } return m } func NewMsgNextBlockAndTxsInRange(block cbor.RawMessage, txs []cbor.RawMessage) *MsgNextBlockAndTxsInRange { - m := &MsgNextBlockAndTxsInRange{ + cloned := make([]cbor.RawMessage, len(txs)) + for i := range txs { + cloned[i] = bytes.Clone(txs[i]) + } + m := &MsgNextBlockAndTxsInRange{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeNextBlockAndTxsInRange, }, - BlockRaw: block, - TxsRaw: slices.Clone(txs), + BlockRaw: bytes.Clone(block), + TxsRaw: cloned, } return m } func NewMsgLastBlockAndTxsInRange(block cbor.RawMessage, txs []cbor.RawMessage) *MsgLastBlockAndTxsInRange { - m := &MsgLastBlockAndTxsInRange{ + cloned := make([]cbor.RawMessage, len(txs)) + for i := range txs { + cloned[i] = bytes.Clone(txs[i]) + } + m := &MsgLastBlockAndTxsInRange{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeLastBlockAndTxsInRange, }, - BlockRaw: block, - TxsRaw: slices.Clone(txs), + BlockRaw: bytes.Clone(block), + TxsRaw: cloned, } return m }Additionally, consider deep‑cloning VoteIssuerId elements:
func NewMsgVotesRequest(voteIds []MsgVotesRequestVoteId) *MsgVotesRequest { - m := &MsgVotesRequest{ + // deep clone ids and nested byte slices + cloned := make([]MsgVotesRequestVoteId, len(voteIds)) + for i := range voteIds { + cloned[i].Slot = voteIds[i].Slot + cloned[i].VoteIssuerId = bytes.Clone(voteIds[i].VoteIssuerId) + } + m := &MsgVotesRequest{ MessageBase: protocol.MessageBase{ MessageType: MessageTypeVotesRequest, }, - VoteIds: slices.Clone(voteIds), + VoteIds: cloned, } return m }Also applies to: 131-139, 167-175, 200-209, 217-226
protocol/leiosfetch/server.go (1)
202-206: Restart on Done: verify concurrent range senders
If BlockRangeRequest spawns async senders, they may still write while Stop/initProtocol/Start swaps s.Protocol. Confirm callbacks tolerate ErrProtocolShuttingDown and won’t leak goroutines. Consider a per‑request context to cancel on Done.protocol/leiosfetch/client.go (1)
43-48: Consider small buffers on result channels to reduce producer blocking
Unbuffered chans can transiently block the protocol goroutine if a response lands before the caller starts waiting. Buffer size 1 (or configurable) for single‑shot responses, and a modest buffer (e.g., 32) for ranges improves resilience.- blockResultChan: make(chan protocol.Message), - blockTxsResultChan: make(chan protocol.Message), - votesResultChan: make(chan protocol.Message), - blockRangeResultChan: make(chan protocol.Message), + blockResultChan: make(chan protocol.Message, 1), + blockTxsResultChan: make(chan protocol.Message, 1), + votesResultChan: make(chan protocol.Message, 1), + blockRangeResultChan: make(chan protocol.Message, 32),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
connection.go(6 hunks)protocol/leiosfetch/client.go(1 hunks)protocol/leiosfetch/leiosfetch.go(1 hunks)protocol/leiosfetch/messages.go(1 hunks)protocol/leiosfetch/server.go(1 hunks)protocol/leiosnotify/leiosnotify.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- connection.go
- protocol/leiosnotify/leiosnotify.go
🧰 Additional context used
🧬 Code graph analysis (4)
protocol/leiosfetch/server.go (4)
protocol/protocol.go (6)
Protocol(39-54)ProtocolOptions(93-102)ProtocolConfig(57-71)ProtocolRoleServer(89-89)MessageHandlerFunc(110-110)MessageFromCborFunc(113-113)protocol/leiosfetch/leiosfetch.go (11)
Config(115-121)CallbackContext(124-128)ProtocolName(26-26)ProtocolId(27-27)StateMap(39-108)StateIdle(31-31)New(138-144)BlockRequestFunc(132-132)BlockTxsRequestFunc(133-133)VotesRequestFunc(134-134)BlockRangeRequestFunc(135-135)protocol/leiosfetch/messages.go (10)
NewMsgFromCbor(41-73)MessageTypeBlockRequest(29-29)MessageTypeBlockTxsRequest(31-31)MessageTypeVotesRequest(33-33)MessageTypeBlockRangeRequest(35-35)MessageTypeDone(38-38)MsgBlockRequest(75-79)MsgBlockTxsRequest(107-112)MsgVotesRequest(141-144)MsgBlockRangeRequest(177-181)protocol/message.go (1)
Message(18-22)
protocol/leiosfetch/client.go (5)
protocol/protocol.go (6)
Protocol(39-54)ProtocolOptions(93-102)ProtocolConfig(57-71)ProtocolRoleClient(88-88)MessageHandlerFunc(110-110)MessageFromCborFunc(113-113)protocol/leiosfetch/leiosfetch.go (12)
Config(115-121)CallbackContext(124-128)NewConfig(148-157)StateMap(39-108)StateBlock(32-32)StateBlockTxs(33-33)StateVotes(34-34)StateBlockRange(35-35)ProtocolName(26-26)ProtocolId(27-27)StateIdle(31-31)New(138-144)protocol/leiosfetch/messages.go (13)
NewMsgFromCbor(41-73)NewMsgDone(232-239)NewMsgBlockRequest(81-90)NewMsgBlockTxsRequest(114-124)MsgVotesRequestVoteId(146-150)NewMsgVotesRequest(152-160)NewMsgBlockRangeRequest(183-192)MsgLastBlockAndTxsInRange(211-215)MessageTypeBlock(30-30)MessageTypeBlockTxs(32-32)MessageTypeVotes(34-34)MessageTypeNextBlockAndTxsInRange(37-37)MessageTypeLastBlockAndTxsInRange(36-36)protocol/error.go (1)
ErrProtocolShuttingDown(19-19)protocol/common/types.go (1)
Point(23-28)
protocol/leiosfetch/leiosfetch.go (8)
protocol/state.go (6)
NewState(38-43)StateMapEntry(62-66)AgencyClient(27-27)StateTransition(51-55)AgencyServer(28-28)AgencyNone(26-26)protocol/leiosfetch/messages.go (11)
MessageTypeBlockRequest(29-29)MessageTypeBlockTxsRequest(31-31)MessageTypeVotesRequest(33-33)MessageTypeBlockRangeRequest(35-35)MessageTypeDone(38-38)MessageTypeBlock(30-30)MessageTypeBlockTxs(32-32)MessageTypeVotes(34-34)MessageTypeNextBlockAndTxsInRange(37-37)MessageTypeLastBlockAndTxsInRange(36-36)MsgVotesRequestVoteId(146-150)protocol/leiosfetch/client.go (2)
Client(25-35)NewClient(37-87)protocol/leiosfetch/server.go (2)
Server(24-29)NewServer(31-43)connection.go (2)
ConnectionId(56-56)New(133-135)protocol/message.go (1)
Message(18-22)protocol/common/types.go (1)
Point(23-28)protocol/protocol.go (1)
ProtocolOptions(93-102)
protocol/leiosfetch/messages.go (5)
protocol/message.go (2)
Message(18-22)MessageBase(25-30)cbor/decode.go (1)
Decode(29-44)protocol/leiosfetch/leiosfetch.go (1)
ProtocolName(26-26)cbor/cbor.go (2)
RawMessage(36-36)StructAsArray(45-48)protocol/common/types.go (1)
Point(23-28)
🔇 Additional comments (3)
protocol/leiosfetch/leiosfetch.go (1)
25-28: Confirm ProtocolId uniqueness and stability across mux
Ensure 19 doesn’t collide with existing/adjacent mini‑protocol IDs and is final for wire compatibility. If undecided, gate behind a const in a central registry or document the allocation.protocol/leiosfetch/server.go (1)
170-176: LGTM: log string matches handler
“block range request” accurately reflects BlockRangeRequest.protocol/leiosfetch/client.go (1)
166-182: LGTM: BlockRangeRequest now consumes from blockRangeResultChan
This resolves the deadlock reported earlier.
Summary by CodeRabbit
New Features
Bug Fixes / Improvements