From b76d0ea9baa83b7608e623ef249fb9f9ffaf7dd5 Mon Sep 17 00:00:00 2001 From: Andrew Gaffney Date: Sat, 19 Feb 2022 14:36:32 -0600 Subject: [PATCH] Properly support protocol versions * create version map for NtN and NtC * switch CBOR encoding mode to ensure ordered map keys --- ouroboros.go | 22 ++++++---- utils/cbor.go | 10 ++++- versions.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 versions.go diff --git a/ouroboros.go b/ouroboros.go index 1bd5507f..1ea81ead 100644 --- a/ouroboros.go +++ b/ouroboros.go @@ -1,7 +1,6 @@ package ouroboros import ( - "fmt" "github.com/cloudstruct/go-ouroboros-network/muxer" "github.com/cloudstruct/go-ouroboros-network/protocol/blockfetch" "github.com/cloudstruct/go-ouroboros-network/protocol/chainsync" @@ -82,21 +81,28 @@ func (o *Ouroboros) setupConnection() error { }() // Perform handshake o.Handshake = handshake.New(o.muxer, o.ErrorChan, o.useNodeToNodeProto) - // TODO: create a proper version map - versionMap := []uint16{1, 32778} + var protoVersions []uint16 if o.useNodeToNodeProto { - versionMap = []uint16{7} + protoVersions = GetProtocolVersionsNtN() + } else { + protoVersions = GetProtocolVersionsNtC() } + // TODO: figure out better way to signify automatic handshaking and returning the chosen version if !o.waitForHandshake { - err := o.Handshake.ProposeVersions(versionMap, o.networkMagic) + err := o.Handshake.ProposeVersions(protoVersions, o.networkMagic) if err != nil { return err } } o.handshakeComplete = <-o.Handshake.Finished - fmt.Printf("negotiated protocol version %d\n", o.Handshake.Version) // TODO: register additional mini-protocols - o.ChainSync = chainsync.New(o.muxer, o.ErrorChan, o.useNodeToNodeProto, o.chainSyncCallbackConfig) - o.BlockFetch = blockfetch.New(o.muxer, o.ErrorChan, o.blockFetchCallbackConfig) + if o.useNodeToNodeProto { + //versionNtN := GetProtocolVersionNtN(o.Handshake.Version) + o.ChainSync = chainsync.New(o.muxer, o.ErrorChan, o.useNodeToNodeProto, o.chainSyncCallbackConfig) + o.BlockFetch = blockfetch.New(o.muxer, o.ErrorChan, o.blockFetchCallbackConfig) + } else { + //versionNtC := GetProtocolVersionNtC(o.Handshake.Version) + o.ChainSync = chainsync.New(o.muxer, o.ErrorChan, o.useNodeToNodeProto, o.chainSyncCallbackConfig) + } return nil } diff --git a/utils/cbor.go b/utils/cbor.go index 790c793b..c983ee50 100644 --- a/utils/cbor.go +++ b/utils/cbor.go @@ -6,8 +6,14 @@ import ( ) func CborEncode(data interface{}) ([]byte, error) { - dataBytes, err := cbor.Marshal(data) - return dataBytes, err + buf := bytes.NewBuffer(nil) + em, err := cbor.CoreDetEncOptions().EncMode() + if err != nil { + return nil, err + } + enc := em.NewEncoder(buf) + err = enc.Encode(data) + return buf.Bytes(), err } func CborDecode(dataBytes []byte, dest interface{}) (int, error) { diff --git a/versions.go b/versions.go new file mode 100644 index 00000000..282a370c --- /dev/null +++ b/versions.go @@ -0,0 +1,114 @@ +package ouroboros + +const ( + // The NtC protocol versions have the 15th bit set in the handshake + PROTOCOL_VERSION_NTC_FLAG = 0x8000 +) + +type ProtocolVersionNtC struct { + // Most of these are enabled in all of the protocol versions that we support, but + // they are here for completeness + EnableLocalQueryProtocol bool + EnableShelleyEra bool + EnableAllegraEra bool + EnableMaryEra bool + EnableAlonzoEra bool + EnableLocalTxMonitorProtocol bool +} + +// We don't bother supporting NtC protocol versions before 9 (when Alonzo was enabled) +var ProtocolVersionMapNtC = map[uint16]ProtocolVersionNtC{ + 9: ProtocolVersionNtC{ + EnableLocalQueryProtocol: true, + EnableShelleyEra: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableAlonzoEra: true, + }, + // This version also adds the GetChainBlockNo and GetChainPoint queries, but we don't + // currently have a flag for this + 10: ProtocolVersionNtC{ + EnableLocalQueryProtocol: true, + EnableShelleyEra: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableAlonzoEra: true, + }, + // This version also adds the GetRewardInfoPools Block query, but we don't currently + // have a flag for this + 11: ProtocolVersionNtC{ + EnableLocalQueryProtocol: true, + EnableShelleyEra: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableAlonzoEra: true, + }, + 12: ProtocolVersionNtC{ + EnableLocalQueryProtocol: true, + EnableShelleyEra: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableAlonzoEra: true, + EnableLocalTxMonitorProtocol: true, + }, +} + +type ProtocolVersionNtN struct { + // Most of these are enabled in all of the protocol versions that we support, but + // they are here for completeness + EnableShelleyEra bool + EnableKeepAliveProtocol bool + EnableAllegraEra bool + EnableMaryEra bool + EnableTxSubmission2Protocol bool + EnableAlonzoEra bool + EnableFullDuplex bool +} + +// We don't bother supporting NtN protocol versions before 7 (when Alonzo was enabled) +var ProtocolVersionMapNtN = map[uint16]ProtocolVersionNtN{ + 7: ProtocolVersionNtN{ + EnableShelleyEra: true, + EnableKeepAliveProtocol: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableTxSubmission2Protocol: true, + EnableAlonzoEra: true, + }, + 8: ProtocolVersionNtN{ + EnableShelleyEra: true, + EnableKeepAliveProtocol: true, + EnableAllegraEra: true, + EnableMaryEra: true, + EnableTxSubmission2Protocol: true, + EnableAlonzoEra: true, + EnableFullDuplex: true, + }, +} + +func GetProtocolVersionsNtC() []uint16 { + versions := []uint16{} + for key := range ProtocolVersionMapNtC { + versions = append(versions, key+PROTOCOL_VERSION_NTC_FLAG) + } + return versions +} + +func GetProtocolVersionNtC(version uint16) ProtocolVersionNtC { + if version > PROTOCOL_VERSION_NTC_FLAG { + version = version - PROTOCOL_VERSION_NTC_FLAG + } + return ProtocolVersionMapNtC[version] +} + +func GetProtocolVersionsNtN() []uint16 { + versions := []uint16{} + for key := range ProtocolVersionMapNtN { + versions = append(versions, key) + } + return versions +} + +func GetProtocolVersionNtN(version uint16) ProtocolVersionNtN { + return ProtocolVersionMapNtN[version] +}