Skip to content

Commit c0455cb

Browse files
authored
feat: support for acquire immutable tip in local-state-query (#811)
* rename (Re)AcquireNoPoint to (Re)AcquireVolatileTip * add new messages for ImmutableTip * add client functions for acquiring volatile/immutable tip * change Acquire callback signature for immutable trip Fixes #766
1 parent 71842b5 commit c0455cb

File tree

6 files changed

+172
-65
lines changed

6 files changed

+172
-65
lines changed

protocol/localstatequery/client.go

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,58 @@ func (c *Client) Start() {
114114

115115
// Acquire starts the acquire process for the specified chain point
116116
func (c *Client) Acquire(point *common.Point) error {
117-
var msg string
118-
if point != nil {
119-
msg = fmt.Sprintf(
120-
"calling Acquire(point: {Slot: %d, Hash: %x})",
121-
point.Slot,
122-
point.Hash,
117+
// Use volatile tip if no point provided
118+
if point == nil {
119+
return c.AcquireVolatileTip()
120+
}
121+
c.Protocol.Logger().
122+
Debug(
123+
fmt.Sprintf(
124+
"calling Acquire(point: {Slot: %d, Hash: %x})",
125+
point.Slot,
126+
point.Hash,
127+
),
128+
"component", "network",
129+
"protocol", ProtocolName,
130+
"role", "client",
131+
"connection_id", c.callbackContext.ConnectionId.String(),
123132
)
124-
} else {
125-
msg = "calling Acquire(point: latest)"
133+
c.busyMutex.Lock()
134+
defer c.busyMutex.Unlock()
135+
acquireTarget := AcquireSpecificPoint{
136+
Point: *point,
126137
}
138+
return c.acquire(acquireTarget)
139+
}
140+
141+
func (c *Client) AcquireVolatileTip() error {
142+
c.Protocol.Logger().
143+
Debug(
144+
"calling AcquireVolatileTip",
145+
"component", "network",
146+
"protocol", ProtocolName,
147+
"role", "client",
148+
"connection_id", c.callbackContext.ConnectionId.String(),
149+
)
150+
c.busyMutex.Lock()
151+
defer c.busyMutex.Unlock()
152+
acquireTarget := AcquireVolatileTip{}
153+
return c.acquire(acquireTarget)
154+
}
127155

156+
func (c *Client) AcquireImmutableTip() error {
128157
c.Protocol.Logger().
129158
Debug(
130-
msg,
159+
"calling AcquireImmutableTip",
131160
"component", "network",
132161
"protocol", ProtocolName,
133162
"role", "client",
134163
"connection_id", c.callbackContext.ConnectionId.String(),
135164
)
136165
c.busyMutex.Lock()
137166
defer c.busyMutex.Unlock()
138-
return c.acquire(point)
167+
acquireTarget := AcquireImmutableTip{}
168+
return c.acquire(acquireTarget)
139169
}
140170

141171
// Release releases the previously acquired chain point
@@ -906,19 +936,29 @@ func (c *Client) handleResult(msg protocol.Message) error {
906936
return nil
907937
}
908938

909-
func (c *Client) acquire(point *common.Point) error {
939+
func (c *Client) acquire(acquireTarget AcquireTarget) error {
910940
var msg protocol.Message
911941
if c.acquired {
912-
if point != nil {
913-
msg = NewMsgReAcquire(*point)
914-
} else {
915-
msg = NewMsgReAcquireNoPoint()
942+
switch t := acquireTarget.(type) {
943+
case AcquireSpecificPoint:
944+
msg = NewMsgReAcquire(t.Point)
945+
case AcquireVolatileTip:
946+
msg = NewMsgReAcquireVolatileTip()
947+
case AcquireImmutableTip:
948+
msg = NewMsgReAcquireImmutableTip()
949+
default:
950+
return fmt.Errorf("invalid acquire point provided")
916951
}
917952
} else {
918-
if point != nil {
919-
msg = NewMsgAcquire(*point)
920-
} else {
921-
msg = NewMsgAcquireNoPoint()
953+
switch t := acquireTarget.(type) {
954+
case AcquireSpecificPoint:
955+
msg = NewMsgAcquire(t.Point)
956+
case AcquireVolatileTip:
957+
msg = NewMsgAcquireVolatileTip()
958+
case AcquireImmutableTip:
959+
msg = NewMsgAcquireImmutableTip()
960+
default:
961+
return fmt.Errorf("invalid acquire point provided")
922962
}
923963
}
924964
if err := c.SendMessage(msg); err != nil {
@@ -944,7 +984,7 @@ func (c *Client) release() error {
944984
func (c *Client) runQuery(query interface{}, result interface{}) error {
945985
msg := NewMsgQuery(query)
946986
if !c.acquired {
947-
if err := c.acquire(nil); err != nil {
987+
if err := c.acquire(AcquireVolatileTip{}); err != nil {
948988
return err
949989
}
950990
}

protocol/localstatequery/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var conversationHandshakeAcquire = []ouroboros_mock.ConversationEntry{
3737
ouroboros_mock.ConversationEntryHandshakeNtCResponse,
3838
ouroboros_mock.ConversationEntryInput{
3939
ProtocolId: localstatequery.ProtocolId,
40-
MessageType: localstatequery.MessageTypeAcquireNoPoint,
40+
MessageType: localstatequery.MessageTypeAcquireVolatileTip,
4141
},
4242
ouroboros_mock.ConversationEntryOutput{
4343
ProtocolId: localstatequery.ProtocolId,

protocol/localstatequery/localstatequery.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ var StateMap = protocol.StateMap{
4747
NewState: stateAcquiring,
4848
},
4949
{
50-
MsgType: MessageTypeAcquireNoPoint,
50+
MsgType: MessageTypeAcquireVolatileTip,
51+
NewState: stateAcquiring,
52+
},
53+
{
54+
MsgType: MessageTypeAcquireImmutableTip,
5155
NewState: stateAcquiring,
5256
},
5357
{
@@ -81,7 +85,11 @@ var StateMap = protocol.StateMap{
8185
NewState: stateAcquiring,
8286
},
8387
{
84-
MsgType: MessageTypeReacquireNoPoint,
88+
MsgType: MessageTypeReacquireVolatileTip,
89+
NewState: stateAcquiring,
90+
},
91+
{
92+
MsgType: MessageTypeReacquireImmutableTip,
8593
NewState: stateAcquiring,
8694
},
8795
{
@@ -121,6 +129,25 @@ type Config struct {
121129
QueryTimeout time.Duration
122130
}
123131

132+
// Acquire target types
133+
type AcquireTarget interface {
134+
isAcquireTarget()
135+
}
136+
137+
type AcquireSpecificPoint struct {
138+
Point common.Point
139+
}
140+
141+
func (AcquireSpecificPoint) isAcquireTarget() {}
142+
143+
type AcquireVolatileTip struct{}
144+
145+
func (AcquireVolatileTip) isAcquireTarget() {}
146+
147+
type AcquireImmutableTip struct{}
148+
149+
func (AcquireImmutableTip) isAcquireTarget() {}
150+
124151
// Callback context
125152
type CallbackContext struct {
126153
ConnectionId connection.ConnectionId
@@ -129,10 +156,10 @@ type CallbackContext struct {
129156
}
130157

131158
// Callback function types
132-
type AcquireFunc func(CallbackContext, *common.Point) error
159+
type AcquireFunc func(CallbackContext, AcquireTarget) error
133160
type QueryFunc func(CallbackContext, any) error
134161
type ReleaseFunc func(CallbackContext) error
135-
type ReAcquireFunc func(CallbackContext, *common.Point) error
162+
type ReAcquireFunc func(CallbackContext, AcquireTarget) error
136163
type DoneFunc func(CallbackContext) error
137164

138165
// New returns a new LocalStateQuery object

protocol/localstatequery/messages.go

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,18 @@ import (
2424

2525
// Message types
2626
const (
27-
MessageTypeAcquire = 0
28-
MessageTypeAcquired = 1
29-
MessageTypeFailure = 2
30-
MessageTypeQuery = 3
31-
MessageTypeResult = 4
32-
MessageTypeRelease = 5
33-
MessageTypeReacquire = 6
34-
MessageTypeDone = 7
35-
MessageTypeAcquireNoPoint = 8
36-
MessageTypeReacquireNoPoint = 9
27+
MessageTypeAcquire = 0
28+
MessageTypeAcquired = 1
29+
MessageTypeFailure = 2
30+
MessageTypeQuery = 3
31+
MessageTypeResult = 4
32+
MessageTypeRelease = 5
33+
MessageTypeReacquire = 6
34+
MessageTypeDone = 7
35+
MessageTypeAcquireVolatileTip = 8
36+
MessageTypeReacquireVolatileTip = 9
37+
MessageTypeAcquireImmutableTip = 10
38+
MessageTypeReacquireImmutableTip = 11
3739
)
3840

3941
// Acquire failure reasons
@@ -60,10 +62,14 @@ func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error) {
6062
ret = &MsgRelease{}
6163
case MessageTypeReacquire:
6264
ret = &MsgReAcquire{}
63-
case MessageTypeAcquireNoPoint:
64-
ret = &MsgAcquireNoPoint{}
65-
case MessageTypeReacquireNoPoint:
66-
ret = &MsgReAcquireNoPoint{}
65+
case MessageTypeAcquireVolatileTip:
66+
ret = &MsgAcquireVolatileTip{}
67+
case MessageTypeReacquireVolatileTip:
68+
ret = &MsgReAcquireVolatileTip{}
69+
case MessageTypeAcquireImmutableTip:
70+
ret = &MsgAcquireImmutableTip{}
71+
case MessageTypeReacquireImmutableTip:
72+
ret = &MsgReAcquireImmutableTip{}
6773
case MessageTypeDone:
6874
ret = &MsgDone{}
6975
}
@@ -92,14 +98,27 @@ func NewMsgAcquire(point common.Point) *MsgAcquire {
9298
return m
9399
}
94100

95-
type MsgAcquireNoPoint struct {
101+
type MsgAcquireVolatileTip struct {
96102
protocol.MessageBase
97103
}
98104

99-
func NewMsgAcquireNoPoint() *MsgAcquireNoPoint {
100-
m := &MsgAcquireNoPoint{
105+
func NewMsgAcquireVolatileTip() *MsgAcquireVolatileTip {
106+
m := &MsgAcquireVolatileTip{
101107
MessageBase: protocol.MessageBase{
102-
MessageType: MessageTypeAcquireNoPoint,
108+
MessageType: MessageTypeAcquireVolatileTip,
109+
},
110+
}
111+
return m
112+
}
113+
114+
type MsgAcquireImmutableTip struct {
115+
protocol.MessageBase
116+
}
117+
118+
func NewMsgAcquireImmutableTip() *MsgAcquireImmutableTip {
119+
m := &MsgAcquireImmutableTip{
120+
MessageBase: protocol.MessageBase{
121+
MessageType: MessageTypeAcquireImmutableTip,
103122
},
104123
}
105124
return m
@@ -191,14 +210,27 @@ func NewMsgReAcquire(point common.Point) *MsgReAcquire {
191210
return m
192211
}
193212

194-
type MsgReAcquireNoPoint struct {
213+
type MsgReAcquireVolatileTip struct {
214+
protocol.MessageBase
215+
}
216+
217+
func NewMsgReAcquireVolatileTip() *MsgReAcquireVolatileTip {
218+
m := &MsgReAcquireVolatileTip{
219+
MessageBase: protocol.MessageBase{
220+
MessageType: MessageTypeReacquireVolatileTip,
221+
},
222+
}
223+
return m
224+
}
225+
226+
type MsgReAcquireImmutableTip struct {
195227
protocol.MessageBase
196228
}
197229

198-
func NewMsgReAcquireNoPoint() *MsgReAcquireNoPoint {
199-
m := &MsgReAcquireNoPoint{
230+
func NewMsgReAcquireImmutableTip() *MsgReAcquireImmutableTip {
231+
m := &MsgReAcquireImmutableTip{
200232
MessageBase: protocol.MessageBase{
201-
MessageType: MessageTypeReacquireNoPoint,
233+
MessageType: MessageTypeReacquireImmutableTip,
202234
},
203235
}
204236
return m

protocol/localstatequery/messages_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ var tests = []testDefinition{
8383
},
8484
{
8585
CborHex: "8108",
86-
Message: NewMsgAcquireNoPoint(),
87-
MessageType: MessageTypeAcquireNoPoint,
86+
Message: NewMsgAcquireVolatileTip(),
87+
MessageType: MessageTypeAcquireVolatileTip,
8888
},
8989
{
9090
CborHex: "8109",
91-
Message: NewMsgReAcquireNoPoint(),
92-
MessageType: MessageTypeReacquireNoPoint,
91+
Message: NewMsgReAcquireVolatileTip(),
92+
MessageType: MessageTypeReacquireVolatileTip,
9393
},
9494
}
9595

protocol/localstatequery/server.go

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ func (s *Server) messageHandler(msg protocol.Message) error {
7575
err = s.handleRelease()
7676
case MessageTypeReacquire:
7777
err = s.handleReAcquire(msg)
78-
case MessageTypeAcquireNoPoint:
78+
case MessageTypeAcquireVolatileTip:
7979
err = s.handleAcquire(msg)
80-
case MessageTypeReacquireNoPoint:
80+
case MessageTypeReacquireVolatileTip:
8181
err = s.handleReAcquire(msg)
8282
case MessageTypeDone:
8383
err = s.handleDone()
@@ -104,15 +104,19 @@ func (s *Server) handleAcquire(msg protocol.Message) error {
104104
"received local-state-query Acquire message but no callback function is defined",
105105
)
106106
}
107+
var acquireTarget AcquireTarget
107108
switch msgAcquire := msg.(type) {
108109
case *MsgAcquire:
109-
// Call the user callback function
110-
return s.config.AcquireFunc(s.callbackContext, &msgAcquire.Point)
111-
case *MsgAcquireNoPoint:
112-
// Call the user callback function
113-
return s.config.AcquireFunc(s.callbackContext, nil)
110+
acquireTarget = AcquireSpecificPoint{
111+
Point: msgAcquire.Point,
112+
}
113+
case *MsgAcquireVolatileTip:
114+
acquireTarget = AcquireVolatileTip{}
115+
case *MsgAcquireImmutableTip:
116+
acquireTarget = AcquireImmutableTip{}
114117
}
115-
return nil
118+
// Call the user callback function
119+
return s.config.AcquireFunc(s.callbackContext, acquireTarget)
116120
}
117121

118122
func (s *Server) handleQuery(msg protocol.Message) error {
@@ -163,15 +167,19 @@ func (s *Server) handleReAcquire(msg protocol.Message) error {
163167
"received local-state-query ReAcquire message but no callback function is defined",
164168
)
165169
}
170+
var acquireTarget AcquireTarget
166171
switch msgReAcquire := msg.(type) {
167172
case *MsgReAcquire:
168-
// Call the user callback function
169-
return s.config.ReAcquireFunc(s.callbackContext, &msgReAcquire.Point)
170-
case *MsgReAcquireNoPoint:
171-
// Call the user callback function
172-
return s.config.ReAcquireFunc(s.callbackContext, nil)
173+
acquireTarget = AcquireSpecificPoint{
174+
Point: msgReAcquire.Point,
175+
}
176+
case *MsgReAcquireVolatileTip:
177+
acquireTarget = AcquireVolatileTip{}
178+
case *MsgReAcquireImmutableTip:
179+
acquireTarget = AcquireImmutableTip{}
173180
}
174-
return nil
181+
// Call the user callback function
182+
return s.config.ReAcquireFunc(s.callbackContext, acquireTarget)
175183
}
176184

177185
func (s *Server) handleDone() error {

0 commit comments

Comments
 (0)