Skip to content

Commit 046d70d

Browse files
authored
Merge pull request #101 from cloudstruct/feature/diffusion-mode
feat: make diffusion mode configurable
2 parents 8750515 + 14e99ea commit 046d70d

File tree

5 files changed

+86
-14
lines changed

5 files changed

+86
-14
lines changed

cmd/go-ouroboros-network/chainsync.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"encoding/hex"
55
"flag"
66
"fmt"
7-
ouroboros "github.com/cloudstruct/go-ouroboros-network"
87
"github.com/cloudstruct/go-cardano-ledger"
8+
ouroboros "github.com/cloudstruct/go-ouroboros-network"
99
"github.com/cloudstruct/go-ouroboros-network/protocol/blockfetch"
1010
"github.com/cloudstruct/go-ouroboros-network/protocol/chainsync"
1111
"github.com/cloudstruct/go-ouroboros-network/utils"
@@ -31,14 +31,15 @@ func newChainSyncFlags() *chainSyncFlags {
3131
f := &chainSyncFlags{
3232
flagset: flag.NewFlagSet("chain-sync", flag.ExitOnError),
3333
}
34-
f.flagset.StringVar(&f.startEra, "start-era", "byron", "era which to start chain-sync at")
34+
f.flagset.StringVar(&f.startEra, "start-era", "genesis", "era which to start chain-sync at")
3535
return f
3636
}
3737

3838
// Intersect points (last block of previous era) for each era on testnet/mainnet
3939
var eraIntersect = map[int]map[string][]interface{}{
4040
TESTNET_MAGIC: map[string][]interface{}{
41-
"byron": []interface{}{},
41+
"genesis": []interface{}{},
42+
"byron": []interface{}{},
4243
// Last block of epoch 73 (Byron era)
4344
"shelley": []interface{}{1598399, "7e16781b40ebf8b6da18f7b5e8ade855d6738095ef2f1c58c77e88b6e45997a4"},
4445
// Last block of epoch 101 (Shelley era)
@@ -51,7 +52,8 @@ var eraIntersect = map[int]map[string][]interface{}{
5152
"babbage": []interface{}{62510369, "d931221f9bc4cae34de422d9f4281a2b0344e86aac6b31eb54e2ee90f44a09b9"},
5253
},
5354
MAINNET_MAGIC: map[string][]interface{}{
54-
"byron": []interface{}{},
55+
"genesis": []interface{}{},
56+
"byron": []interface{}{},
5557
// Last block of epoch 207 (Byron era)
5658
"shelley": []interface{}{4492799, "f8084c61b6a238acec985b59310b6ecec49c0ab8352249afd7268da5cff2a457"},
5759
// Last block of epoch 235 (Shelley era)
@@ -62,6 +64,16 @@ var eraIntersect = map[int]map[string][]interface{}{
6264
"alonzo": []interface{}{39916796, "e72579ff89dc9ed325b723a33624b596c08141c7bd573ecfff56a1f7229e4d09"},
6365
// TODO: add Babbage starting point after mainnet hard fork
6466
},
67+
PREPROD_MAGIC: map[string][]interface{}{
68+
"genesis": []interface{}{},
69+
"alonzo": []interface{}{},
70+
},
71+
PREVIEW_MAGIC: map[string][]interface{}{
72+
"genesis": []interface{}{},
73+
"alonzo": []interface{}{},
74+
// Last block of epoch 3 (Alonzo era)
75+
"babbage": []interface{}{345599, "6e4de9c9b2dcc2436488aa8a6ce584250a45b42583c5d3d0749597bcf59dc0b5"},
76+
},
6577
}
6678

6779
func buildChainSyncCallbackConfig() *chainsync.ChainSyncCallbackConfig {

cmd/go-ouroboros-network/main.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
const (
1212
TESTNET_MAGIC = 1097911063
1313
MAINNET_MAGIC = 764824073
14+
PREPROD_MAGIC = 1
15+
PREVIEW_MAGIC = 2
1416
)
1517

1618
type globalFlags struct {
@@ -22,7 +24,8 @@ type globalFlags struct {
2224
networkMagic int
2325
testnet bool
2426
mainnet bool
25-
syncEra string
27+
preprod bool
28+
preview bool
2629
}
2730

2831
func newGlobalFlags() *globalFlags {
@@ -36,7 +39,8 @@ func newGlobalFlags() *globalFlags {
3639
f.flagset.IntVar(&f.networkMagic, "network-magic", 0, "network magic value")
3740
f.flagset.BoolVar(&f.testnet, "testnet", false, fmt.Sprintf("alias for -network-magic=%d", TESTNET_MAGIC))
3841
f.flagset.BoolVar(&f.mainnet, "mainnet", false, fmt.Sprintf("alias for -network-magic=%d", MAINNET_MAGIC))
39-
f.flagset.StringVar(&f.syncEra, "sync-era", "byron", "era which to start chain-sync at")
42+
f.flagset.BoolVar(&f.preprod, "preprod", false, fmt.Sprintf("alias for -network-magic=%d", PREPROD_MAGIC))
43+
f.flagset.BoolVar(&f.preview, "preview", false, fmt.Sprintf("alias for -network-magic=%d", PREVIEW_MAGIC))
4044
return f
4145
}
4246

@@ -53,8 +57,12 @@ func main() {
5357
f.networkMagic = TESTNET_MAGIC
5458
} else if f.mainnet {
5559
f.networkMagic = MAINNET_MAGIC
60+
} else if f.preprod {
61+
f.networkMagic = PREPROD_MAGIC
62+
} else if f.preview {
63+
f.networkMagic = PREVIEW_MAGIC
5664
} else {
57-
fmt.Printf("You must specify one of -testnet, -mainnet, or -network-magic\n\n")
65+
fmt.Printf("You must specify one of -testnet, -mainnet, -preprod, -preview, or -network-magic\n\n")
5866
flag.PrintDefaults()
5967
os.Exit(1)
6068
}

muxer/muxer.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ const (
1717
PROTOCOL_HANDSHAKE = 0
1818
)
1919

20+
type DiffusionMode int
21+
22+
var (
23+
DiffusionModeNone DiffusionMode = 0
24+
DiffusionModeInitiator DiffusionMode = 1
25+
DiffusionModeResponder DiffusionMode = 2
26+
DiffusionModeInitiatorAndResponder DiffusionMode = 3
27+
)
28+
2029
type Muxer struct {
2130
conn net.Conn
2231
sendMutex sync.Mutex
@@ -26,6 +35,7 @@ type Muxer struct {
2635
ErrorChan chan error
2736
protocolSenders map[uint16]chan *Segment
2837
protocolReceivers map[uint16]chan *Segment
38+
diffusionMode DiffusionMode
2939
}
3040

3141
func New(conn net.Conn) *Muxer {
@@ -67,6 +77,10 @@ func (m *Muxer) Stop() {
6777
close(m.ErrorChan)
6878
}
6979

80+
func (m *Muxer) SetDiffusionMode(diffusionMode DiffusionMode) {
81+
m.diffusionMode = diffusionMode
82+
}
83+
7084
func (m *Muxer) sendError(err error) {
7185
// Immediately return if we're already shutting down
7286
select {
@@ -148,6 +162,16 @@ func (m *Muxer) readLoop() {
148162
m.sendError(err)
149163
return
150164
}
165+
// Check for message from initiator when we're not configured as a responder
166+
if m.diffusionMode == DiffusionModeInitiator && !msg.IsResponse() {
167+
m.sendError(fmt.Errorf("received message from initiator when not configured as a responder"))
168+
return
169+
}
170+
// Check for message from responder when we're not configured as an initiator
171+
if m.diffusionMode == DiffusionModeResponder && msg.IsResponse() {
172+
m.sendError(fmt.Errorf("received message from responder when not configured as an initiator"))
173+
return
174+
}
151175
// Send message payload to proper receiver
152176
recvChan := m.protocolReceivers[msg.GetProtocolId()]
153177
if recvChan == nil {

ouroboros.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Ouroboros struct {
2525
protoErrorChan chan error
2626
sendKeepAlives bool
2727
delayMuxerStart bool
28+
fullDuplex bool
2829
// Mini-protocols
2930
Handshake *handshake.Handshake
3031
ChainSync *chainsync.ChainSync
@@ -43,6 +44,7 @@ type OuroborosOptions struct {
4344
UseNodeToNodeProtocol bool
4445
SendKeepAlives bool
4546
DelayMuxerStart bool
47+
FullDuplex bool
4648
}
4749

4850
func New(options *OuroborosOptions) (*Ouroboros, error) {
@@ -54,6 +56,7 @@ func New(options *OuroborosOptions) (*Ouroboros, error) {
5456
ErrorChan: options.ErrorChan,
5557
sendKeepAlives: options.SendKeepAlives,
5658
delayMuxerStart: options.DelayMuxerStart,
59+
fullDuplex: options.FullDuplex,
5760
protoErrorChan: make(chan error, 10),
5861
}
5962
if o.ErrorChan == nil {
@@ -134,7 +137,7 @@ func (o *Ouroboros) setupConnection() error {
134137
o.Handshake.Start()
135138
// TODO: figure out better way to signify automatic handshaking and returning the chosen version
136139
if !o.server {
137-
err := o.Handshake.ProposeVersions(protoVersions, o.networkMagic)
140+
err := o.Handshake.ProposeVersions(protoVersions, o.networkMagic, o.fullDuplex)
138141
if err != nil {
139142
return err
140143
}
@@ -182,6 +185,13 @@ func (o *Ouroboros) setupConnection() error {
182185
}
183186
}
184187
// Start muxer
188+
diffusionMode := muxer.DiffusionModeInitiator
189+
if o.Handshake.FullDuplex {
190+
diffusionMode = muxer.DiffusionModeInitiatorAndResponder
191+
} else if o.server {
192+
diffusionMode = muxer.DiffusionModeResponder
193+
}
194+
o.muxer.SetDiffusionMode(diffusionMode)
185195
if !o.delayMuxerStart {
186196
o.muxer.Start()
187197
}

protocol/handshake/handshake.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const (
99
PROTOCOL_NAME = "handshake"
1010
PROTOCOL_ID = 0
1111

12-
DIFFUSION_MODE_INITIATOR_ONLY = true
13-
DIFFUSION_MODE_INITIATOR_AND_RESPONDER = false
12+
DIFFUSION_MODE_INITIATOR_ONLY = false
13+
DIFFUSION_MODE_INITIATOR_AND_RESPONDER = true
1414
)
1515

1616
var (
@@ -51,6 +51,7 @@ type Handshake struct {
5151
*protocol.Protocol
5252
allowedVersions []uint16
5353
Version uint16
54+
FullDuplex bool
5455
Finished chan bool
5556
}
5657

@@ -94,12 +95,16 @@ func (h *Handshake) handleMessage(msg protocol.Message, isResponse bool) error {
9495
return err
9596
}
9697

97-
func (h *Handshake) ProposeVersions(versions []uint16, networkMagic uint32) error {
98+
func (h *Handshake) ProposeVersions(versions []uint16, networkMagic uint32, fullDuplex bool) error {
9899
// Create our request
99100
versionMap := make(map[uint16]interface{})
101+
diffusionMode := DIFFUSION_MODE_INITIATOR_ONLY
102+
if fullDuplex {
103+
diffusionMode = DIFFUSION_MODE_INITIATOR_AND_RESPONDER
104+
}
100105
for _, version := range versions {
101106
if h.Mode() == protocol.ProtocolModeNodeToNode {
102-
versionMap[version] = []interface{}{networkMagic, DIFFUSION_MODE_INITIATOR_ONLY}
107+
versionMap[version] = []interface{}{networkMagic, diffusionMode}
103108
} else {
104109
versionMap[version] = networkMagic
105110
}
@@ -111,13 +116,20 @@ func (h *Handshake) ProposeVersions(versions []uint16, networkMagic uint32) erro
111116
func (h *Handshake) handleProposeVersions(msgGeneric protocol.Message) error {
112117
msg := msgGeneric.(*MsgProposeVersions)
113118
var highestVersion uint16
114-
var versionData interface{}
119+
var fullDuplex bool
120+
var versionData []interface{}
115121
for proposedVersion := range msg.VersionMap {
116122
if proposedVersion > highestVersion {
117123
for _, allowedVersion := range h.allowedVersions {
118124
if allowedVersion == proposedVersion {
119125
highestVersion = proposedVersion
120-
versionData = msg.VersionMap[proposedVersion]
126+
versionData = msg.VersionMap[proposedVersion].([]interface{})
127+
//nolint:gosimple
128+
if versionData[1].(bool) == DIFFUSION_MODE_INITIATOR_AND_RESPONDER {
129+
fullDuplex = true
130+
} else {
131+
fullDuplex = false
132+
}
121133
break
122134
}
123135
}
@@ -129,6 +141,7 @@ func (h *Handshake) handleProposeVersions(msgGeneric protocol.Message) error {
129141
return err
130142
}
131143
h.Version = highestVersion
144+
h.FullDuplex = fullDuplex
132145
h.Finished <- true
133146
return nil
134147
} else {
@@ -141,6 +154,11 @@ func (h *Handshake) handleProposeVersions(msgGeneric protocol.Message) error {
141154
func (h *Handshake) handleAcceptVersion(msgGeneric protocol.Message) error {
142155
msg := msgGeneric.(*MsgAcceptVersion)
143156
h.Version = msg.Version
157+
versionData := msg.VersionData.([]interface{})
158+
//nolint:gosimple
159+
if versionData[1].(bool) == DIFFUSION_MODE_INITIATOR_AND_RESPONDER {
160+
h.FullDuplex = true
161+
}
144162
h.Finished <- true
145163
return nil
146164
}

0 commit comments

Comments
 (0)