Skip to content

Commit 1670124

Browse files
authored
Merge pull request #43 from cloudstruct/feature/local-state-query-protocol
Implement local-state-query mini-protocol (part 1)
2 parents 824ed3d + ae22772 commit 1670124

File tree

4 files changed

+472
-6
lines changed

4 files changed

+472
-6
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ but the node-to-node protocols will also be implemented in time.
1919
| Name | Status |
2020
| --- | --- |
2121
| Handshake | Implemented |
22-
| Chain-Sync | Implemented |
23-
| Block-Fetch | Implemented |
24-
| TxSubmission | Not Implemented |
25-
| Local TxSubmission | Implemented |
26-
| Local State Query | Not Implemented |
27-
| Keep-Alive | Implemented |
22+
| ChainSync | Implemented |
23+
| BlockFetch | Implemented |
24+
| TxSubmission2 | Not Implemented |
25+
| LocalTxSubmission | Implemented |
26+
| LocalStateQuery | Partly Implemented |
27+
| KeepAlive | Implemented |
28+
| LocalTxMonitor | Not Implemented |
2829

2930
## Testing
3031

ouroboros.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/cloudstruct/go-ouroboros-network/protocol/chainsync"
88
"github.com/cloudstruct/go-ouroboros-network/protocol/handshake"
99
"github.com/cloudstruct/go-ouroboros-network/protocol/keepalive"
10+
"github.com/cloudstruct/go-ouroboros-network/protocol/localstatequery"
1011
"github.com/cloudstruct/go-ouroboros-network/protocol/localtxsubmission"
1112
"net"
1213
)
@@ -31,6 +32,8 @@ type Ouroboros struct {
3132
keepAliveCallbackConfig *keepalive.KeepAliveCallbackConfig
3233
LocalTxSubmission *localtxsubmission.LocalTxSubmission
3334
localTxSubmissionCallbackConfig *localtxsubmission.CallbackConfig
35+
LocalStateQuery *localstatequery.LocalStateQuery
36+
localStateQueryCallbackConfig *localstatequery.CallbackConfig
3437
}
3538

3639
type OuroborosOptions struct {
@@ -45,6 +48,7 @@ type OuroborosOptions struct {
4548
BlockFetchCallbackConfig *blockfetch.BlockFetchCallbackConfig
4649
KeepAliveCallbackConfig *keepalive.KeepAliveCallbackConfig
4750
LocalTxSubmissionCallbackConfig *localtxsubmission.CallbackConfig
51+
LocalStateQueryCallbackConfig *localstatequery.CallbackConfig
4852
}
4953

5054
func New(options *OuroborosOptions) (*Ouroboros, error) {
@@ -57,6 +61,7 @@ func New(options *OuroborosOptions) (*Ouroboros, error) {
5761
blockFetchCallbackConfig: options.BlockFetchCallbackConfig,
5862
keepAliveCallbackConfig: options.KeepAliveCallbackConfig,
5963
localTxSubmissionCallbackConfig: options.LocalTxSubmissionCallbackConfig,
64+
localStateQueryCallbackConfig: options.LocalStateQueryCallbackConfig,
6065
ErrorChan: options.ErrorChan,
6166
sendKeepAlives: options.SendKeepAlives,
6267
delayMuxerStart: options.DelayMuxerStart,
@@ -140,6 +145,7 @@ func (o *Ouroboros) setupConnection() error {
140145
protoOptions.Mode = protocol.ProtocolModeNodeToClient
141146
o.ChainSync = chainsync.New(protoOptions, o.chainSyncCallbackConfig)
142147
o.LocalTxSubmission = localtxsubmission.New(protoOptions, o.localTxSubmissionCallbackConfig)
148+
o.LocalStateQuery = localstatequery.New(protoOptions, o.localStateQueryCallbackConfig)
143149
}
144150
if !o.delayMuxerStart {
145151
o.muxer.Start()
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
package localstatequery
2+
3+
import (
4+
"fmt"
5+
"github.com/cloudstruct/go-ouroboros-network/protocol"
6+
)
7+
8+
const (
9+
PROTOCOL_NAME = "local-state-query"
10+
PROTOCOL_ID uint16 = 7
11+
)
12+
13+
var (
14+
STATE_IDLE = protocol.NewState(1, "Idle")
15+
STATE_ACQUIRING = protocol.NewState(2, "Acquiring")
16+
STATE_ACQUIRED = protocol.NewState(3, "Acquired")
17+
STATE_QUERYING = protocol.NewState(4, "Querying")
18+
STATE_DONE = protocol.NewState(5, "Done")
19+
)
20+
21+
var StateMap = protocol.StateMap{
22+
STATE_IDLE: protocol.StateMapEntry{
23+
Agency: protocol.AGENCY_SERVER,
24+
Transitions: []protocol.StateTransition{
25+
{
26+
MsgType: MESSAGE_TYPE_ACQUIRE,
27+
NewState: STATE_ACQUIRING,
28+
},
29+
{
30+
MsgType: MESSAGE_TYPE_ACQUIRE_NO_POINT,
31+
NewState: STATE_ACQUIRING,
32+
},
33+
{
34+
MsgType: MESSAGE_TYPE_DONE,
35+
NewState: STATE_DONE,
36+
},
37+
},
38+
},
39+
STATE_ACQUIRING: protocol.StateMapEntry{
40+
Agency: protocol.AGENCY_CLIENT,
41+
Transitions: []protocol.StateTransition{
42+
{
43+
MsgType: MESSAGE_TYPE_FAILURE,
44+
NewState: STATE_IDLE,
45+
},
46+
{
47+
MsgType: MESSAGE_TYPE_ACQUIRED,
48+
NewState: STATE_ACQUIRED,
49+
},
50+
},
51+
},
52+
STATE_ACQUIRED: protocol.StateMapEntry{
53+
Agency: protocol.AGENCY_SERVER,
54+
Transitions: []protocol.StateTransition{
55+
{
56+
MsgType: MESSAGE_TYPE_QUERY,
57+
NewState: STATE_QUERYING,
58+
},
59+
{
60+
MsgType: MESSAGE_TYPE_REACQUIRE,
61+
NewState: STATE_ACQUIRING,
62+
},
63+
{
64+
MsgType: MESSAGE_TYPE_REACQUIRE_NO_POINT,
65+
NewState: STATE_ACQUIRING,
66+
},
67+
{
68+
MsgType: MESSAGE_TYPE_RELEASE,
69+
NewState: STATE_IDLE,
70+
},
71+
},
72+
},
73+
STATE_QUERYING: protocol.StateMapEntry{
74+
Agency: protocol.AGENCY_CLIENT,
75+
Transitions: []protocol.StateTransition{
76+
{
77+
MsgType: MESSAGE_TYPE_RESULT,
78+
NewState: STATE_ACQUIRED,
79+
},
80+
},
81+
},
82+
STATE_DONE: protocol.StateMapEntry{
83+
Agency: protocol.AGENCY_NONE,
84+
},
85+
}
86+
87+
type LocalStateQuery struct {
88+
proto *protocol.Protocol
89+
callbackConfig *CallbackConfig
90+
}
91+
92+
type CallbackConfig struct {
93+
AcquireFunc AcquireFunc
94+
AcquiredFunc AcquiredFunc
95+
FailureFunc FailureFunc
96+
QueryFunc QueryFunc
97+
ResultFunc ResultFunc
98+
ReleaseFunc ReleaseFunc
99+
ReAcquireFunc ReAcquireFunc
100+
DoneFunc DoneFunc
101+
}
102+
103+
// Callback function types
104+
// TODO: update callbacks
105+
type AcquireFunc func(interface{}) error
106+
type AcquiredFunc func() error
107+
type FailureFunc func(interface{}) error
108+
type QueryFunc func(interface{}) error
109+
type ResultFunc func(interface{}) error
110+
type ReleaseFunc func() error
111+
type ReAcquireFunc func(interface{}) error
112+
type DoneFunc func() error
113+
114+
func New(options protocol.ProtocolOptions, callbackConfig *CallbackConfig) *LocalStateQuery {
115+
l := &LocalStateQuery{
116+
callbackConfig: callbackConfig,
117+
}
118+
protoConfig := protocol.ProtocolConfig{
119+
Name: PROTOCOL_NAME,
120+
ProtocolId: PROTOCOL_ID,
121+
Muxer: options.Muxer,
122+
ErrorChan: options.ErrorChan,
123+
Mode: options.Mode,
124+
Role: options.Role,
125+
MessageHandlerFunc: l.messageHandler,
126+
MessageFromCborFunc: NewMsgFromCbor,
127+
StateMap: StateMap,
128+
InitialState: STATE_IDLE,
129+
}
130+
l.proto = protocol.New(protoConfig)
131+
return l
132+
}
133+
134+
func (l *LocalStateQuery) messageHandler(msg protocol.Message, isResponse bool) error {
135+
var err error
136+
switch msg.Type() {
137+
case MESSAGE_TYPE_ACQUIRE:
138+
err = l.handleAcquire(msg)
139+
case MESSAGE_TYPE_ACQUIRED:
140+
err = l.handleAcquired()
141+
case MESSAGE_TYPE_FAILURE:
142+
err = l.handleFailure(msg)
143+
case MESSAGE_TYPE_QUERY:
144+
err = l.handleQuery(msg)
145+
case MESSAGE_TYPE_RESULT:
146+
err = l.handleResult(msg)
147+
case MESSAGE_TYPE_RELEASE:
148+
err = l.handleRelease()
149+
case MESSAGE_TYPE_REACQUIRE:
150+
err = l.handleReAcquire(msg)
151+
case MESSAGE_TYPE_ACQUIRE_NO_POINT:
152+
err = l.handleAcquire(msg)
153+
case MESSAGE_TYPE_REACQUIRE_NO_POINT:
154+
err = l.handleReAcquire(msg)
155+
case MESSAGE_TYPE_DONE:
156+
err = l.handleDone()
157+
default:
158+
err = fmt.Errorf("%s: received unexpected message type %d", PROTOCOL_NAME, msg.Type())
159+
}
160+
return err
161+
}
162+
163+
func (l *LocalStateQuery) handleAcquire(msg protocol.Message) error {
164+
if l.callbackConfig.AcquireFunc == nil {
165+
return fmt.Errorf("received local-state-query Acquire message but no callback function is defined")
166+
}
167+
switch msgAcquire := msg.(type) {
168+
case *MsgAcquire:
169+
// Call the user callback function
170+
return l.callbackConfig.AcquireFunc(msgAcquire.Point)
171+
case *MsgAcquireNoPoint:
172+
// Call the user callback function
173+
return l.callbackConfig.AcquireFunc(nil)
174+
}
175+
return nil
176+
}
177+
178+
func (l *LocalStateQuery) handleAcquired() error {
179+
if l.callbackConfig.AcquiredFunc == nil {
180+
return fmt.Errorf("received local-state-query Acquired message but no callback function is defined")
181+
}
182+
// Call the user callback function
183+
return l.callbackConfig.AcquiredFunc()
184+
}
185+
186+
func (l *LocalStateQuery) handleFailure(msg protocol.Message) error {
187+
if l.callbackConfig.FailureFunc == nil {
188+
return fmt.Errorf("received local-state-query Failure message but no callback function is defined")
189+
}
190+
msgFailure := msg.(*MsgFailure)
191+
// Call the user callback function
192+
return l.callbackConfig.FailureFunc(msgFailure.Failure)
193+
}
194+
195+
func (l *LocalStateQuery) handleQuery(msg protocol.Message) error {
196+
if l.callbackConfig.QueryFunc == nil {
197+
return fmt.Errorf("received local-state-query Query message but no callback function is defined")
198+
}
199+
msgQuery := msg.(*MsgQuery)
200+
// Call the user callback function
201+
return l.callbackConfig.QueryFunc(msgQuery.Query)
202+
}
203+
204+
func (l *LocalStateQuery) handleResult(msg protocol.Message) error {
205+
if l.callbackConfig.ResultFunc == nil {
206+
return fmt.Errorf("received local-state-query Result message but no callback function is defined")
207+
}
208+
msgResult := msg.(*MsgResult)
209+
// Call the user callback function
210+
return l.callbackConfig.ResultFunc(msgResult.Result)
211+
}
212+
213+
func (l *LocalStateQuery) handleRelease() error {
214+
if l.callbackConfig.ReleaseFunc == nil {
215+
return fmt.Errorf("received local-state-query Release message but no callback function is defined")
216+
}
217+
// Call the user callback function
218+
return l.callbackConfig.ReleaseFunc()
219+
}
220+
221+
func (l *LocalStateQuery) handleReAcquire(msg protocol.Message) error {
222+
if l.callbackConfig.ReAcquireFunc == nil {
223+
return fmt.Errorf("received local-state-query ReAcquire message but no callback function is defined")
224+
}
225+
switch msgReAcquire := msg.(type) {
226+
case *MsgReAcquire:
227+
// Call the user callback function
228+
return l.callbackConfig.ReAcquireFunc(msgReAcquire.Point)
229+
case *MsgReAcquireNoPoint:
230+
// Call the user callback function
231+
return l.callbackConfig.ReAcquireFunc(nil)
232+
}
233+
return nil
234+
}
235+
236+
func (l *LocalStateQuery) handleDone() error {
237+
if l.callbackConfig.DoneFunc == nil {
238+
return fmt.Errorf("received local-state-query Done message but no callback function is defined")
239+
}
240+
// Call the user callback function
241+
return l.callbackConfig.DoneFunc()
242+
}

0 commit comments

Comments
 (0)