Repository: dusk-network/dusk-blockchain (go)

Issue:
Protocol versioning behaviour
**The protocol versioning needs to be properly specc'ed**

- If the nodes receive a message with a version that cannot be processed (since it is newer), they should ignore the message
- when we do the handshake with the bootstrapper, the version of the protocol (and the node, and rusk) should be validated. The bootstrapper will probe the version communicated by the nodes and returns a string with the link to where a newer version shall be downloaded
- the ping/pong could be used to communicate/inquiry the protocol version
- in the header of the messages we should add the protocol version
- consensus version shall remain backward compatible (and therefore consensus version should not influence protocol version)
- protocol changes need to be assessed on a case-by-case basis

## Version binary format

The version is represented as a 64-bit number (8 bytes) loosely following[^1] [semantic versioning]( https://semver.org/) with the format below:

| Field | Offset | Type |Description |
| - |  - | - | - |
| RESERVED | 0 | n/a | For future use |
| MAJOR | 2 | `u16` LE[^2] | version with incompatible API changes |
| MINOR | 4 | `u16` LE| version with added functionality in a backwards compatible manner |
| PATCH  | 6 | `u16` LE | version with backwards compatible bug fixes |

### Testnet

Testnet is always considered with `MAJOR` field set to `0`[^3], therefore the semantic of the field is shifted, merging all backwards compatible changes together[^4]:

| Field | Offset | Type |Description |
| - |  - | - | - |
| RESERVED | 0 | n/a | For future use |
| MAJOR | 2 | `u16` LE | Initial development, value blocked to `0x00` |
| MINOR | 4 | `u16` LE | version with incompatible API changes |
| PATCH  | 6 | `u16` LE |version with any backwards compatible changes |


[^1]: We don't have additional labels for pre-release and build metadata, as the semantic versioning allows.
[^2]: Little Endian
[^3]: Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable. https://semver.org/#spec-item-4
[^4]: This is consistent with the semver we have in rust development in Dusk

Pull request:
Introduce protocol version
- [x]  Check Protocol version
- [x] Setup Node Version and InterOp Version
- [x] Adapt tests with new txs

Resolves #1319

Patch:
diff --git a/cmd/dusk/main.go b/cmd/dusk/main.go
index 90664395..a8857981 100644
--- a/cmd/dusk/main.go
+++ b/cmd/dusk/main.go
@@ -11,7 +11,9 @@ import (
 	"os"
 	"time"
 
+	"github.com/Masterminds/semver"
 	"github.com/dusk-network/dusk-blockchain/cmd/dusk/genesis"
+	cfg "github.com/dusk-network/dusk-blockchain/pkg/config"
 	"github.com/sirupsen/logrus"
 	"github.com/urfave/cli"
 )
@@ -33,7 +35,7 @@ func init() {
 	app.Name = "dusk"
 	app.Usage = "Official Dusk command-line interface"
 	app.Author = "DUSK 2020"
-	app.Version = "0.0.1"
+	app.Version = semver.MustParse(cfg.NodeVersion).String()
 	app.Commands = []cli.Command{
 		{
 			Name:    "genesis",
diff --git a/cmd/dusk/server.go b/cmd/dusk/server.go
index 4d065b34..696a8b2b 100644
--- a/cmd/dusk/server.go
+++ b/cmd/dusk/server.go
@@ -175,7 +175,7 @@ func Setup() *Server {
 	readerFactory := peer.NewReaderFactory(processor)
 
 	// Create the listener and contact the voucher seeder
-	gossip := protocol.NewGossip(protocol.TestNet)
+	gossip := protocol.NewGossip()
 
 	if !cfg.Get().Kadcast.Enabled {
 		connector := peer.NewConnector(eventBus, gossip, cfg.Get().Network.Port, processor, protocol.ServiceFlag(cfg.Get().Network.ServiceFlag), peer.Create)
diff --git a/cmd/voucher/action.go b/cmd/voucher/action.go
index 96cc5964..c36b8b38 100644
--- a/cmd/voucher/action.go
+++ b/cmd/voucher/action.go
@@ -49,7 +49,7 @@ func action(ctx *cli.Context) error {
 	processor.Register(topics.Pong, responding.ProcessPong)
 
 	port := ctx.Int(portFlag.Name)
-	c := peer.NewConnector(eb, protocol.NewGossip(protocol.TestNet), strconv.Itoa(port), processor, protocol.VoucherNode, challenger.SendChallenge)
+	c := peer.NewConnector(eb, protocol.NewGossip(), strconv.Itoa(port), processor, protocol.VoucherNode, challenger.SendChallenge)
 
 	log.
 		WithField("port", port).
diff --git a/cmd/voucher/challenger/challenger.go b/cmd/voucher/challenger/challenger.go
index 5156cc6a..b3f022aa 100644
--- a/cmd/voucher/challenger/challenger.go
+++ b/cmd/voucher/challenger/challenger.go
@@ -32,7 +32,7 @@ type Challenger struct {
 
 // New creates a new, initialized Challenger.
 func New(store *node.Store) *Challenger {
-	return &Challenger{nodes: store, gossip: protocol.NewGossip(protocol.TestNet)}
+	return &Challenger{nodes: store, gossip: protocol.NewGossip()}
 }
 
 // SendChallenge to a connecting peer.
diff --git a/go.mod b/go.mod
index 08623c9f..427f35c3 100644
--- a/go.mod
+++ b/go.mod
@@ -37,6 +37,7 @@ require (
 )
 
 require (
+	github.com/Masterminds/semver v1.5.0
 	github.com/OneOfOne/xxhash v1.2.5 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
diff --git a/go.sum b/go.sum
index e9574949..f17361ed 100644
--- a/go.sum
+++ b/go.sum
@@ -16,6 +16,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
 github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
 github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
diff --git a/harness/engine/utils.go b/harness/engine/utils.go
index b04cf2a3..2a60e2e0 100644
--- a/harness/engine/utils.go
+++ b/harness/engine/utils.go
@@ -9,7 +9,6 @@ package engine
 import (
 	"bytes"
 	"context"
-	"encoding/hex"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -17,6 +16,7 @@ import (
 	"net"
 	"net/http"
 	"path/filepath"
+	"strings"
 	"testing"
 	"time"
 
@@ -137,7 +137,7 @@ func (n *Network) SendWireMsg(ind uint, msg []byte, writeTimeout int) error {
 		return err
 	}
 
-	gossip := protocol.NewGossip(protocol.TestNet)
+	gossip := protocol.NewGossip()
 	pConn := peer.NewConnection(conn, gossip)
 	w := peer.NewWriter(pConn, nil)
 
@@ -161,9 +161,9 @@ func (n *Network) SendWireMsg(ind uint, msg []byte, writeTimeout int) error {
 }
 
 // ConstructWireFrame creates a frame according to the wire protocol.
-func ConstructWireFrame(magic protocol.Magic, cmd topics.Topic, payload *bytes.Buffer) ([]byte, error) {
+func ConstructWireFrame(cmd topics.Topic, payload *bytes.Buffer) ([]byte, error) {
 	// Write magic
-	buf := magic.ToBuffer()
+	buf := protocol.VersionAsBuffer()
 	// Write topic
 	if err := topics.Write(&buf, cmd); err != nil {
 		return nil, err
@@ -422,18 +422,19 @@ func (n *Network) GetWalletAddress(ind uint) (string, []byte, error) {
 	addressFile := filepath.Join(walletsPath, fmt.Sprintf("node_%d.address", ind))
 
 	addressBytes, err := ioutil.ReadFile(filepath.Clean(addressFile))
-	if err != nil {
+	if err != nil || len(addressBytes) == 0 {
 		return "N/A", nil, err
 	}
 
-	addressHex := string(addressBytes)
+	addressString := string(addressBytes)
+	addressString = strings.ReplaceAll(addressString, "\r", "")
+	addressString = strings.ReplaceAll(addressString, "\n", "")
 
-	addressBytes, err = hex.DecodeString(addressHex)
 	if err != nil {
 		return "N/A", nil, err
 	}
 
-	return addressHex, addressBytes, nil
+	return addressString, addressBytes, nil
 }
 
 // GetBalance makes an attempt to get wallet balance of a specified node.
diff --git a/pkg/config/consts.go b/pkg/config/consts.go
index 3854a7e5..c6467ad3 100644
--- a/pkg/config/consts.go
+++ b/pkg/config/consts.go
@@ -35,6 +35,12 @@ const (
 
 	// KadcastInitialHeight sets the default initial height for Kadcast broadcast algorithm.
 	KadcastInitialHeight byte = 128
+
+	// The dusk-blockchain executable version.
+	NodeVersion = "0.5.0"
+
+	// The shared API version (between dusk-blockchain and rusk).
+	InteropVersion = "0.1.0"
 )
 
 // KadcastInitHeader is used as default initial kadcast message header.
diff --git a/pkg/core/database/heavy/database.go b/pkg/core/database/heavy/database.go
index 7974bb9a..4a455c96 100755
--- a/pkg/core/database/heavy/database.go
+++ b/pkg/core/database/heavy/database.go
@@ -11,7 +11,6 @@ import (
 	"sync"
 
 	"github.com/dusk-network/dusk-blockchain/pkg/core/database"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/syndtr/goleveldb/leveldb"
 	"github.com/syndtr/goleveldb/leveldb/errors"
 )
@@ -82,7 +81,7 @@ func closeStorage() error {
 // NewDatabase create or open backend storage (goleveldb) located at the
 // specified path. Readonly option is pseudo read-only mode implemented by
 // heavy.Database. Not to be confused with read-only goleveldb mode.
-func NewDatabase(path string, network protocol.Magic, readonly bool) (database.DB, error) {
+func NewDatabase(path string, readonly bool) (database.DB, error) {
 	storage, err := openStorage(path)
 	if err != nil {
 		return nil, err
diff --git a/pkg/core/database/heavy/driver.go b/pkg/core/database/heavy/driver.go
index 8c0c9774..6a3f90e1 100644
--- a/pkg/core/database/heavy/driver.go
+++ b/pkg/core/database/heavy/driver.go
@@ -9,7 +9,6 @@ package heavy
 import (
 	cfg "github.com/dusk-network/dusk-blockchain/pkg/config"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/database"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -18,8 +17,8 @@ var DriverName = "heavy_v0.1.0"
 
 type driver struct{}
 
-func (d *driver) Open(path string, network protocol.Magic, readonly bool) (database.DB, error) {
-	return NewDatabase(path, network, readonly)
+func (d *driver) Open(path string, readonly bool) (database.DB, error) {
+	return NewDatabase(path, readonly)
 }
 
 func (d *driver) Close() error {
@@ -46,7 +45,7 @@ func CreateDBConnection() (database.Driver, database.DB) {
 		log.Panic(err)
 	}
 
-	db, err := drvr.Open(cfg.Get().Database.Dir, protocol.MagicFromConfig(), false)
+	db, err := drvr.Open(cfg.Get().Database.Dir, false)
 	if err != nil {
 		log.Panic(err)
 	}
diff --git a/pkg/core/database/interfaces.go b/pkg/core/database/interfaces.go
index 4079b1cb..dc8d123c 100644
--- a/pkg/core/database/interfaces.go
+++ b/pkg/core/database/interfaces.go
@@ -12,7 +12,6 @@ import (
 
 	"github.com/dusk-network/dusk-blockchain/pkg/core/data/block"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/data/ipc/transactions"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 )
 
 var (
@@ -41,7 +40,7 @@ var (
 type Driver interface {
 	// Open returns a new connection to a blockchain database. The path is a
 	// string in a driver-specific format.
-	Open(path string, network protocol.Magic, readonly bool) (DB, error)
+	Open(path string, readonly bool) (DB, error)
 
 	// Close terminates all DB connections and closes underlying storage.
 	Close() error
diff --git a/pkg/core/database/lite/database.go b/pkg/core/database/lite/database.go
index 207e83a1..dd999641 100755
--- a/pkg/core/database/lite/database.go
+++ b/pkg/core/database/lite/database.go
@@ -10,7 +10,6 @@ import (
 	"sync"
 
 	"github.com/dusk-network/dusk-blockchain/pkg/core/database"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 )
 
 type (
@@ -45,7 +44,7 @@ type DB struct {
 // This should be the ideal situation with lowest latency on storing or fetching data.
 // In-memory only (as result autoDeleted).
 // multi-instances (no singleton).
-func NewDatabase(path string, network protocol.Magic, readonly bool) (database.DB, error) {
+func NewDatabase(path string, readonly bool) (database.DB, error) {
 	var db *DB
 	var tables [maxInd]table
 
diff --git a/pkg/core/database/lite/driver.go b/pkg/core/database/lite/driver.go
index 59652bd0..81bc1425 100644
--- a/pkg/core/database/lite/driver.go
+++ b/pkg/core/database/lite/driver.go
@@ -8,7 +8,6 @@ package lite
 
 import (
 	"github.com/dusk-network/dusk-blockchain/pkg/core/database"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -17,8 +16,8 @@ var DriverName = "lite_v0.1.0"
 
 type driver struct{}
 
-func (d *driver) Open(path string, network protocol.Magic, readonly bool) (database.DB, error) {
-	return NewDatabase(path, network, readonly)
+func (d *driver) Open(path string, readonly bool) (database.DB, error) {
+	return NewDatabase(path, readonly)
 }
 
 func (d *driver) Close() error {
@@ -43,7 +42,7 @@ func CreateDBConnection() (database.Driver, database.DB) {
 		log.Panic(err)
 	}
 
-	db, err := drvr.Open("", protocol.TestNet, false)
+	db, err := drvr.Open("", false)
 	if err != nil {
 		log.Panic(err)
 	}
diff --git a/pkg/p2p/wire/protocol/frame.go b/pkg/p2p/wire/protocol/frame.go
index ef750ce4..09927b69 100644
--- a/pkg/p2p/wire/protocol/frame.go
+++ b/pkg/p2p/wire/protocol/frame.go
@@ -11,7 +11,6 @@ import (
 	"encoding/binary"
 	"fmt"
 	"io"
-	"time"
 
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/checksum"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/encoding"
@@ -23,11 +22,14 @@ const (
 
 	// reservedFieldSize is number of bytes the reserved field uses.
 	reservedFieldSize = 8
+
+	// VersionLength is number of bytes the version uses.
+	VersionLength = uint64(8)
 )
 
 // WriteFrame mutates a buffer by adding a length-prefixing wire message frame at the beginning of the message.
-func WriteFrame(buf *bytes.Buffer, magic Magic, cs []byte) error {
-	ln := uint64(magic.Len() + reservedFieldSize + checksum.Length + buf.Len())
+func WriteFrame(buf *bytes.Buffer, cs []byte) error {
+	ln := VersionLength + uint64(reservedFieldSize+checksum.Length+buf.Len())
 	if ln > MaxFrameSize {
 		return fmt.Errorf("message size exceeds MaxFrameSize (%d)", MaxFrameSize)
 	}
@@ -38,18 +40,14 @@ func WriteFrame(buf *bytes.Buffer, magic Magic, cs []byte) error {
 		return err
 	}
 
-	// Add magic
-	mBuf := magic.ToBuffer()
-	if _, err := msg.Write(mBuf.Bytes()); err != nil {
+	// Add version
+	vBuf := VersionAsBuffer()
+	if _, err := msg.Write(vBuf.Bytes()); err != nil {
 		return err
 	}
 
 	// Add reserved field bytes
 	var reserved uint64
-	if magic == TestNet || magic == DevNet {
-		// populate reserved fields with timestamp
-		reserved = uint64(time.Now().UnixNano())
-	}
 
 	if err := encoding.WriteUint64LE(msg, reserved); err != nil {
 		return err
diff --git a/pkg/p2p/wire/protocol/gossip.go b/pkg/p2p/wire/protocol/gossip.go
index 3e8fd1fb..7be7f2be 100644
--- a/pkg/p2p/wire/protocol/gossip.go
+++ b/pkg/p2p/wire/protocol/gossip.go
@@ -19,7 +19,6 @@ import (
 type (
 	// Gossip is a preprocessor/reader for gossip messages.
 	Gossip struct {
-		Magic Magic
 	}
 )
 
@@ -31,17 +30,15 @@ TODO:
 */
 
 // NewGossip returns a gossip preprocessor with the specified magic.
-func NewGossip(magic Magic) *Gossip {
-	return &Gossip{
-		Magic: magic,
-	}
+func NewGossip() *Gossip {
+	return &Gossip{}
 }
 
 // Process a message that is passing through, by prepending
 // magic and the message checksum, and finally by prepending the length.
 func (g *Gossip) Process(m *bytes.Buffer) error {
 	cs := checksum.Generate(m.Bytes())
-	return WriteFrame(m, g.Magic, cs)
+	return WriteFrame(m, cs)
 }
 
 // UnpackLength unwraps the incoming packet (likely from a net.Conn struct) and returns the length of the packet without reading the payload (which is left to the user of this method).
@@ -51,11 +48,15 @@ func (g *Gossip) UnpackLength(r io.Reader) (uint64, error) {
 		return 0, err
 	}
 
-	magic, err := Extract(r)
+	version, err := ExtractVersion(r)
 	if err != nil {
 		return 0, err
 	}
 
+	if !VersionConstraint.Check(version) {
+		return 0, fmt.Errorf("invalid message version %s received, expected %s", version, VersionConstraintString)
+	}
+
 	// if magic != g.Magic {
 	// 	return 0, fmt.Errorf("magic mismatch, received %s expected %s", magic, g.Magic)
 	// }
@@ -71,7 +72,7 @@ func (g *Gossip) UnpackLength(r io.Reader) (uint64, error) {
 
 	// If packetLength is less than magic.Len(), ln is close to MaxUint64
 	// due to integer overflow
-	ln := packetLength - uint64(rfSize) - uint64(magic.Len())
+	ln := packetLength - uint64(rfSize) - VersionLength
 
 	if ln > MaxFrameSize {
 		return 0, fmt.Errorf("invalid packet length %d", packetLength)
diff --git a/pkg/p2p/wire/protocol/protocol.go b/pkg/p2p/wire/protocol/protocol.go
index eed49eca..79e15a21 100755
--- a/pkg/p2p/wire/protocol/protocol.go
+++ b/pkg/p2p/wire/protocol/protocol.go
@@ -8,12 +8,10 @@ package protocol
 
 import (
 	"bytes"
-	"encoding/binary"
 	"fmt"
 	"io"
-	"strings"
 
-	cfg "github.com/dusk-network/dusk-blockchain/pkg/config"
+	"github.com/Masterminds/semver"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/encoding"
 	log "github.com/sirupsen/logrus"
 )
@@ -33,110 +31,78 @@ const (
 )
 
 // NodeVer is the current node version.
+// This is used only in the handshake, need to be removed.
 var NodeVer = &Version{
 	Major: 0,
 	Minor: 4,
 	Patch: 3,
 }
 
-// Magic is the network that Dusk is running on.
-type Magic uint8
+// CurrentProtocolVersion indicates the protocol version used.
+var CurrentProtocolVersion = semver.MustParse("0.1.0")
 
-const (
-	// MainNet identifies the production network of the Dusk blockchain.
-	MainNet Magic = iota
-	// TestNet identifies the test network of the Dusk blockchain.
-	TestNet
-	// DevNet identifies the development network of the Dusk blockchain.
-	DevNet
-	// StressNet identifies the stress testing network of the Dusk blockchain.
-	StressNet
-)
-
-const (
-	mainnetUint32 uint32 = 0x7630401f
-	testnetUint32 uint32 = 0x74746e41
-	//nolint
-	devnetUint32    uint32 = 0x74736e40
-	stressnetUint32 uint32 = 0x74726e39
-)
-
-type magicObj struct {
-	Magic
-	buf bytes.Buffer
-	str string
-}
+// VersionConstraintString represent the needed version.
+const VersionConstraintString = "~0.1.0"
 
-var magics = [...]magicObj{
-	{MainNet, asBuffer(0x7630401f), "mainnet"},
-	{TestNet, asBuffer(0x74746e41), "testnet"},
-	{DevNet, asBuffer(0x74736e40), "devnet"},
-	{StressNet, asBuffer(0x74726e39), "stressnet"},
-}
+// VersionConstraint check incoming versions.
+var VersionConstraint, _ = semver.NewConstraint(VersionConstraintString)
 
-// Len returns the amount of bytes of the Magic sequence.
-func (m Magic) Len() int {
-	return magics[m].buf.Len()
-}
+// VersionAsBuffer returns protocol version encoded as BytesBuffer.
+func VersionAsBuffer() bytes.Buffer {
+	buf := new(bytes.Buffer)
 
-// String representation of Magic.
-func (m Magic) String() string {
-	return magics[m].str
-}
+	if err := encoding.WriteUint16LE(buf, uint16(0)); err != nil {
+		log.Panic(err)
+	}
 
-// ToBuffer returns the buffer representation of the Magic.
-func (m Magic) ToBuffer() bytes.Buffer {
-	return magics[m].buf
-}
+	if err := encoding.WriteUint16LE(buf, uint16(CurrentProtocolVersion.Major())); err != nil {
+		log.Panic(err)
+	}
 
-func fromUint32(n uint32) Magic {
-	switch n {
-	case mainnetUint32:
-		return MainNet
-	case testnetUint32:
-		return TestNet
-	case stressnetUint32:
-		return StressNet
-	default:
-		return DevNet
+	if err := encoding.WriteUint16LE(buf, uint16(CurrentProtocolVersion.Minor())); err != nil {
+		log.Panic(err)
 	}
-}
 
-func asBuffer(magic uint32) bytes.Buffer {
-	buf := new(bytes.Buffer)
-	if err := encoding.WriteUint32LE(buf, magic); err != nil {
+	if err := encoding.WriteUint16LE(buf, uint16(CurrentProtocolVersion.Patch())); err != nil {
 		log.Panic(err)
 	}
+
 	return *buf
 }
 
-// MagicFromConfig reads the loaded magic config and tries to map it to magic
-// identifier. Panic, if no match found.
-func MagicFromConfig() Magic {
-	magic := cfg.Get().General.Network
-	mstr := strings.ToLower(magic)
+// ExtractVersion extracts the version from io.Reader.
+func ExtractVersion(r io.Reader) (*semver.Version, error) {
+	buffer := make([]byte, 8)
+	if _, err := io.ReadFull(r, buffer); err != nil {
+		return nil, err
+	}
+
+	buf := bytes.NewBuffer(buffer)
 
-	for _, m := range magics {
-		if mstr == m.str {
-			return m.Magic
-		}
+	reserved := uint16(0)
+	if err := encoding.ReadUint16LE(buf, &reserved); err != nil {
+		return nil, err
 	}
 
-	// An invalid network identifier might cause node unexpected behavior.
-	log.Panic(fmt.Sprintf("not a valid network: %s", magic))
-	return 0
-}
+	major := uint16(0)
+	if err := encoding.ReadUint16LE(buf, &major); err != nil {
+		return nil, err
+	}
 
-// Extract the magic from io.Reader. In case of unknown Magic, it returns DevNet.
-func Extract(r io.Reader) (Magic, error) {
-	buffer := make([]byte, 4)
-	// `ReadFull` is used here, as using a plain `Read` call from a net.Conn could
-	// result in the read finishing before the buffer is filled. Using `ReadFull`
-	// prevents unintended 'magic mismatch' errors.
-	if _, err := io.ReadFull(r, buffer); err != nil {
-		return Magic(byte(255)), err
+	minor := uint16(0)
+	if err := encoding.ReadUint16LE(buf, &minor); err != nil {
+		return nil, err
+	}
+
+	patch := uint16(0)
+	if err := encoding.ReadUint16LE(buf, &patch); err != nil {
+		return nil, err
+	}
+
+	version, err := semver.NewVersion(fmt.Sprintf("%d.%d.%d", major, minor, patch))
+	if err != nil {
+		return nil, err
 	}
 
-	magic := binary.LittleEndian.Uint32(buffer)
-	return fromUint32(magic), nil
+	return version, nil
 }
diff --git a/pkg/util/nativeutils/eventbus/mock.go b/pkg/util/nativeutils/eventbus/mock.go
index 346500fa..10fa20c0 100644
--- a/pkg/util/nativeutils/eventbus/mock.go
+++ b/pkg/util/nativeutils/eventbus/mock.go
@@ -47,7 +47,7 @@ func (m *Collector) Collect(b message.Message) error {
 // gossip topic, and sets the right preprocessors up for the gossip topic.
 func CreateGossipStreamer() (*EventBus, *GossipStreamer) {
 	eb := New()
-	streamer := NewGossipStreamer(protocol.TestNet)
+	streamer := NewGossipStreamer()
 	streamListener := NewStreamListener(streamer)
 	eb.Subscribe(topics.Gossip, streamListener)
 	return eb, streamer
@@ -57,7 +57,7 @@ func CreateGossipStreamer() (*EventBus, *GossipStreamer) {
 // gossip topic, and sets the right preprocessors up for the gossip topic.
 func CreateFrameStreamer(topic topics.Topic) (*EventBus, ring.Writer) {
 	eb := New()
-	streamer := NewSimpleStreamer(protocol.TestNet)
+	streamer := NewSimpleStreamer()
 	streamListener := NewStreamListener(streamer)
 	eb.Subscribe(topic, streamListener)
 	return eb, streamer
@@ -136,14 +136,14 @@ type SimpleStreamer struct {
 }
 
 // NewSimpleStreamer returns an initialized SimpleStreamer.
-func NewSimpleStreamer(magic protocol.Magic) *SimpleStreamer {
+func NewSimpleStreamer() *SimpleStreamer {
 	r, w := io.Pipe()
 
 	return &SimpleStreamer{
 		seenTopics: make([]topics.Topic, 0),
 		Reader:     bufio.NewReader(r),
 		Writer:     bufio.NewWriter(w),
-		gossip:     protocol.NewGossip(magic),
+		gossip:     protocol.NewGossip(),
 	}
 }
 
@@ -187,9 +187,9 @@ type GossipStreamer struct {
 }
 
 // NewGossipStreamer creates a new GossipStreamer instance.
-func NewGossipStreamer(magic protocol.Magic) *GossipStreamer {
+func NewGossipStreamer() *GossipStreamer {
 	return &GossipStreamer{
-		SimpleStreamer: NewSimpleStreamer(magic),
+		SimpleStreamer: NewSimpleStreamer(),
 	}
 }
 


Test patch:
diff --git a/pkg/core/candidate/requestor_test.go b/pkg/core/candidate/requestor_test.go
index 7fed0df5..d5c4b7a3 100644
--- a/pkg/core/candidate/requestor_test.go
+++ b/pkg/core/candidate/requestor_test.go
@@ -15,7 +15,6 @@ import (
 	"github.com/dusk-network/dusk-blockchain/pkg/config/genesis"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/data/block"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/message"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/topics"
 	"github.com/dusk-network/dusk-blockchain/pkg/util/nativeutils/eventbus"
 	assert "github.com/stretchr/testify/require"
@@ -55,7 +54,7 @@ func TestRequestor(t *testing.T) {
 
 	c := genesis.Decode()
 
-	streamer := eventbus.NewGossipStreamer(protocol.TestNet)
+	streamer := eventbus.NewGossipStreamer()
 
 	l := eventbus.NewStreamListener(streamer)
 	bus.Subscribe(topics.Gossip, l)
diff --git a/pkg/core/chain/chain_test.go b/pkg/core/chain/chain_test.go
index c790cc81..a4d18f7b 100644
--- a/pkg/core/chain/chain_test.go
+++ b/pkg/core/chain/chain_test.go
@@ -27,7 +27,6 @@ import (
 	"github.com/dusk-network/dusk-blockchain/pkg/core/loop"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/tests/helper"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/message"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/topics"
 	"github.com/dusk-network/dusk-blockchain/pkg/util/nativeutils/eventbus"
 	"github.com/dusk-network/dusk-blockchain/pkg/util/nativeutils/rpcbus"
@@ -103,7 +102,7 @@ func TestAcceptFromPeer(t *testing.T) {
 	startingHeight := uint64(1)
 	eb, c := setupChainTest(t, startingHeight)
 
-	streamer := eventbus.NewGossipStreamer(protocol.TestNet)
+	streamer := eventbus.NewGossipStreamer()
 	l := eventbus.NewStreamListener(streamer)
 	eb.Subscribe(topics.Gossip, l)
 
diff --git a/pkg/core/consensus/reduction/secondstep/reduction_test.go b/pkg/core/consensus/reduction/secondstep/reduction_test.go
index ed7e4ba4..2a4543ad 100644
--- a/pkg/core/consensus/reduction/secondstep/reduction_test.go
+++ b/pkg/core/consensus/reduction/secondstep/reduction_test.go
@@ -14,7 +14,6 @@ import (
 	"github.com/dusk-network/dusk-blockchain/pkg/core/consensus"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/consensus/reduction"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/message"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/topics"
 	"github.com/dusk-network/dusk-blockchain/pkg/util/nativeutils/eventbus"
 	crypto "github.com/dusk-network/dusk-crypto/hash"
@@ -146,7 +145,7 @@ func TestSecondStepReduction(t *testing.T) {
 
 	table := initiateTableTest(timeout, hash, round, step)
 	for name, ttest := range table {
-		streamer := eventbus.NewGossipStreamer(protocol.TestNet)
+		streamer := eventbus.NewGossipStreamer()
 		streamListener := eventbus.NewStreamListener(streamer)
 
 		// creating the Helper
diff --git a/pkg/core/consensus/reduction/testutil.go b/pkg/core/consensus/reduction/testutil.go
index 0fcb0e3a..2654745e 100644
--- a/pkg/core/consensus/reduction/testutil.go
+++ b/pkg/core/consensus/reduction/testutil.go
@@ -23,7 +23,6 @@ import (
 	"github.com/dusk-network/dusk-blockchain/pkg/core/consensus/key"
 	"github.com/dusk-network/dusk-blockchain/pkg/core/consensus/user"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/message"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/topics"
 )
 
@@ -33,7 +32,7 @@ func PrepareSendReductionTest(hlp *Helper, stepFn consensus.PhaseFn) func(t *tes
 	return func(t *testing.T) {
 		require := require.New(t)
 
-		streamer := eventbus.NewGossipStreamer(protocol.TestNet)
+		streamer := eventbus.NewGossipStreamer()
 		l := eventbus.NewStreamListener(streamer)
 		hlp.EventBus.Subscribe(topics.Gossip, l)
 
diff --git a/pkg/core/database/driver_test.go b/pkg/core/database/driver_test.go
index 54d88652..dd0bacf0 100644
--- a/pkg/core/database/driver_test.go
+++ b/pkg/core/database/driver_test.go
@@ -8,8 +8,6 @@ package database
 
 import (
 	"testing"
-
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 )
 
 func unregisterAllDrivers() {
@@ -23,7 +21,7 @@ func unregisterAllDrivers() {
 // Dummy DriverA.
 type driverA struct{}
 
-func (d driverA) Open(path string, network protocol.Magic, readonly bool) (DB, error) {
+func (d driverA) Open(path string, readonly bool) (DB, error) {
 	return nil, nil
 }
 
@@ -38,7 +36,7 @@ func (d driverA) Close() error {
 // Dummy DriverB.
 type driverB struct{}
 
-func (d driverB) Open(path string, network protocol.Magic, readonly bool) (DB, error) {
+func (d driverB) Open(path string, readonly bool) (DB, error) {
 	return nil, nil
 }
 
diff --git a/pkg/core/database/testing/drivers_test.go b/pkg/core/database/testing/drivers_test.go
index 079dfb8f..58fe3a49 100644
--- a/pkg/core/database/testing/drivers_test.go
+++ b/pkg/core/database/testing/drivers_test.go
@@ -30,7 +30,6 @@ import (
 	// to the blockchain database layer requirements.
 
 	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/message"
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	crypto "github.com/dusk-network/dusk-crypto/hash"
 )
 
@@ -104,7 +103,7 @@ func _TestDriver(m *testing.M, driverName string) int {
 
 	// Create a Database instance to use the temp directory. Multiple
 	// database instances can work concurrently
-	db, err = drvr.Open(storeDir, protocol.DevNet, false)
+	db, err = drvr.Open(storeDir, false)
 	if err != nil {
 		fmt.Println(err)
 		return 1
@@ -480,7 +479,7 @@ func TestReadOnlyDB_Mode(test *testing.T) {
 	// Create database in read-write mode
 	readonly := false
 
-	dbReadWrite, err := drvr.Open(storeDir, protocol.DevNet, readonly)
+	dbReadWrite, err := drvr.Open(storeDir, readonly)
 	if err != nil {
 		test.Fatal(err.Error())
 	}
@@ -496,7 +495,7 @@ func TestReadOnlyDB_Mode(test *testing.T) {
 	// Re-open the storage in read-only mode
 	readonly = true
 
-	dbReadOnly, err := drvr.Open(storeDir, protocol.DevNet, readonly)
+	dbReadOnly, err := drvr.Open(storeDir, readonly)
 	if err != nil {
 		test.Fatal(err.Error())
 	}
@@ -704,7 +703,7 @@ func _TestPersistence() int {
 
 	// Force reload storage and fetch blocks
 	{
-		db, err := drvr.Open(newStoreDir, protocol.DevNet, true)
+		db, err := drvr.Open(newStoreDir, true)
 		defer func() {
 			_ = drvr.Close()
 		}()
diff --git a/pkg/p2p/kadcast/peer_test.go b/pkg/p2p/kadcast/peer_test.go
index 1254d39d..0e77c9cf 100644
--- a/pkg/p2p/kadcast/peer_test.go
+++ b/pkg/p2p/kadcast/peer_test.go
@@ -43,7 +43,7 @@ func TestListenStreamReader(t *testing.T) {
 	// basic infrastructure
 	eb := eventbus.New()
 	p := peer.NewMessageProcessor(eb)
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 
 	// have a callback ready for Block topic
 	respFn := func(srcPeerID string, m message.Message) ([]bytes.Buffer, error) {
@@ -96,7 +96,7 @@ func TestBroadcastWriter(t *testing.T) {
 
 	// Basic infrastructure
 	eb := eventbus.New()
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 
 	// create a mock client
 	cli := NewMockNetworkClient(rcvChan)
diff --git a/pkg/p2p/peer/handshake_test.go b/pkg/p2p/peer/handshake_test.go
index 9befca5f..64c21148 100644
--- a/pkg/p2p/peer/handshake_test.go
+++ b/pkg/p2p/peer/handshake_test.go
@@ -36,12 +36,12 @@ func TestHandshake(t *testing.T) {
 
 	client, srv := net.Pipe()
 
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 	pConn := NewConnection(client, g)
 	pw := NewWriter(pConn, eb)
 
 	go func() {
-		pConn := NewConnection(srv, protocol.NewGossip(protocol.TestNet))
+		pConn := NewConnection(srv, protocol.NewGossip())
 
 		peerReader := factory.SpawnReader(pConn)
 		if err := peerReader.Accept(protocol.FullNode); err != nil {
diff --git a/pkg/p2p/peer/peer_in_test.go b/pkg/p2p/peer/peer_in_test.go
index f5d1b150..257c6e8f 100644
--- a/pkg/p2p/peer/peer_in_test.go
+++ b/pkg/p2p/peer/peer_in_test.go
@@ -51,11 +51,11 @@ func TestPingLoop(t *testing.T) {
 
 	cfg.Mock(&r)
 
-	pConn := NewConnection(client, protocol.NewGossip(protocol.TestNet))
+	pConn := NewConnection(client, protocol.NewGossip())
 	writer := NewWriter(pConn, bus)
 
 	// Set up the other end of the exchange
-	pConn2 := NewConnection(srv, protocol.NewGossip(protocol.TestNet))
+	pConn2 := NewConnection(srv, protocol.NewGossip())
 	writer2 := NewWriter(pConn2, bus)
 
 	// Set up reader factory
@@ -108,7 +108,7 @@ func TestIncompleteChecksum(t *testing.T) {
 	}
 
 	// Add correct magic value
-	mBuf := protocol.TestNet.ToBuffer()
+	mBuf := protocol.VersionAsBuffer()
 	if _, err := frame.Write(mBuf.Bytes()); err != nil {
 		t.Error(err)
 	}
@@ -147,7 +147,7 @@ func TestZeroLength(t *testing.T) {
 	}
 
 	// Add correct magic value
-	mBuf := protocol.TestNet.ToBuffer()
+	mBuf := protocol.VersionAsBuffer()
 	if _, err := frame.Write(mBuf.Bytes()); err != nil {
 		t.Error(err)
 	}
@@ -211,7 +211,7 @@ func TestInvalidPayload(t *testing.T) {
 		buf.Write([]byte{0, 1, 2})
 
 		cs := checksum.Generate(buf.Bytes())
-		_ = protocol.WriteFrame(buf, protocol.TestNet, cs)
+		_ = protocol.WriteFrame(buf, cs)
 
 		_, err := w.Write(buf.Bytes())
 		if err != nil {
@@ -227,7 +227,7 @@ func testReader(t *testing.T, f *ReaderFactory) (*Reader, net.Conn, net.Conn, ch
 	r, w := net.Pipe()
 
 	respChan := make(chan bytes.Buffer, 10)
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 	c := NewConnection(r, g)
 	peer := f.SpawnReader(c)
 
diff --git a/pkg/p2p/peer/peer_test.go b/pkg/p2p/peer/peer_test.go
index 6f576f0e..d34c061f 100644
--- a/pkg/p2p/peer/peer_test.go
+++ b/pkg/p2p/peer/peer_test.go
@@ -34,7 +34,7 @@ var receiveFn = func(c net.Conn) {
 
 // Test the functionality of the peer.Reader through the ReadLoop.
 func TestReader(t *testing.T) {
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 	client, srv := net.Pipe()
 
 	eb := eventbus.New()
@@ -50,7 +50,7 @@ func TestReader(t *testing.T) {
 	processor.Register(topics.Agreement, respFn)
 	factory := NewReaderFactory(processor)
 
-	pConn := NewConnection(srv, protocol.NewGossip(protocol.TestNet))
+	pConn := NewConnection(srv, protocol.NewGossip())
 	peerReader := factory.SpawnReader(pConn)
 
 	peerReader.services = protocol.FullNode
@@ -126,7 +126,7 @@ func makeAgreementGossip(keyAmount int) message.Message {
 
 func addPeer(bus *eventbus.EventBus, receiveFunc func(net.Conn)) *Writer {
 	client, srv := net.Pipe()
-	g := protocol.NewGossip(protocol.TestNet)
+	g := protocol.NewGossip()
 	pConn := NewConnection(client, g)
 	pw := NewWriter(pConn, bus)
 
diff --git a/pkg/p2p/wire/message/transactions_test.go b/pkg/p2p/wire/message/transactions_test.go
index c9fd32d8..af482b7c 100644
--- a/pkg/p2p/wire/message/transactions_test.go
+++ b/pkg/p2p/wire/message/transactions_test.go
@@ -23,8 +23,8 @@ import (
 func TestWireTransaction(t *testing.T) {
 	assert := assert.New(t)
 
-	hexWire := "9f08000000000000406e737400000000000000005a65065d0a0100000001000000520800000100000000000000de45f7c56d19993299e46e28cdefe80444bfbcc558679173d8a5c068f6abd3060200000000000000014dabcafdc6d211035a03d688cc83e09e01a89b58d5604aae7fa70196d58da6c315ce6aba274054f337bdd92d9411d8be3f282b05e3c6d42e8eea9f3215b8de33b96a3c7c1dbcb4d8cdd8ef13e50e84cf6480116311677676269d3e662cea608c5a3479e042102a78621252a37f2d99e6824e17a2b11597147d1adf4624e7d436ffffffffffffffff9974f2345e356dc48137c1d115176c60c5dbf0ea77dd8cdca0cfbc0f3d90304ecb5b2b3d60a2b9d4df4a999ef3a768f8bd75c75aac343bff35bed7cfb2e35133befb1d16048306e60895b1b5fc7d270b33542897cec4bca5d0b9ae826949960901e549d068cb470cbefe6fddd3b2d8aacfa5a76805e725d5394e882a79d157695ec48dcb7e531ccc3b334ae122d4fd40e242e7d8a85fdb82bd4c9e9621a9a60d042dbbaec8a2acb879b48d311f1264b1aafe6bf26ccc0bb250af7a2e19e8dcdc3851f382c509fb449a701a93c9489ae97bae88feaebe38fc6c128dc4b286724c10ffffffffffffffff14b611da24f94e89dd03121410f05b53c52cfc785da3c8d59bb65d07b78ab0241c6a8f3ffadc251790b9f78a31b82246c883cbfa1330337bd094045c01dcca2a7de1eadf6f1f7116169ed9dd10541a407035bb8fe834a973d8176f51f07a8435bb463366c465e470f1b7501917b906a9db5607cb3ef57c1b8bd7c9725063647300ca9a3b000000000100000000000000d85dbd596fc0476c779f3e2e7b5e58b732cb71f9ca056a8828cf845885a22f17848a28b1224942eb4222b7c43fc01e60529c7ee5fab115f3802c91179d0edfa1a0e6aa001633252dc50d9a3e9e3dc7b23365251db481b45ec8f1cf4a4a7e3f036c3ee0b4dc438d98157fb886cce964ba8c1265b99e8fa21418e6ab8f56520f0a704db35fa84a53eadf24e8a4f8a180aa2516e69a47ec10cd2dabde3d5658a3fe97f327062fab1f3b7ceb1c7150a12c02d78ce32d51b885514603ebfdee8cac69700b5ab2c1bf08b690111e0c953a088c91782f75fc2a8b1c4c5bf4aacff3ecafe94311cf5e2c94d1ac441f7c01b2ddcde8c0facb7f746d91addab1282d06506da02d1446630ee85e39d9abecf2aa3c9ba53289bd03332a8182bee045a5dd8115b26fcc34bc637f2d21797f4dae564d79b199c25c51ea17e757ba45ea39a402afd63862e6e353e459a00cd068ac2b759cd6352bf540dc74118bb1fe821c4922f690cc8698b7f162c3932524f8f17941afd213fa9899cf3d58922534a9c21b0667f74307e9b3abe4aedce41f1af6621daeb9648a588c5a1ec0df7a423932b191fee9226e57f59f83256cb15c952ee2bdf472219a873b12f638b6d51ca06e2cbf9783e3feec7f213ed06f7c45c0240858204f8ba25e36f5877be3ade9d68b1b6e1cf49651e11f44e8a11984b29a5f149bdd91f3624e2107579274c406fbda788f5cabcb472a5fe93243b76bcbfc946cc8da600cd7458e428736fe4545259b2a2eda8aab3c187836afae79ec333c9918431b7f6ac024d96d9d83dbbda9084c95ca4999a129f9a6bdc62b09bda93a850e0807b5ea9844531571b1fd99cafffb20614fa7c48ecfcde95184769bf34bcc3fdc4273be119bb5c29ee1290e1e920634543fb7e4f72f439a12ca8888cc6febd7fb1158abb02023fa85ec5c0670be51e5a87fde49e0dd5dfa9e7d2c8679e6ced9b212852c88cce5d8333fc9ce4c91f2d00f80a0b1412ec7f6340a9f237b47e25eb42074c528c2e733ad1fcc7186ffff4a352c848fee121fa3262ea4fd53ecc9e79e2390b6519be98404248cb7ab11bd9fc004250092d7cccff76ab21f7371e7716a844728d768a2872caa191fad3932dd69bba6ebbb2666e75150f967d757d6c8b316ab1275bb9344682f851bef8e205cbdf42f075773275198d982cad99d0a4aff45f612e27ddbaf46744ce527cf62ef7f72bca5e7990997697611787ef1827a071447059954fa85f2eb23906a3e6aa78e514e104a80e63960ab77a206edb830be39c37c9e5d727cf22ab6588b1365ca05f7c21d51ceb1b56720f3c4f4302cff1044facadb7c59c13907ba9bfda92dce75a67b608278dfd6b3ec90160cc07cb3801e70dcee28684e10076d32d82ecd26ebcb445fd5998baf983e5ac13d70263b881aacc01a39223cda26281a3afd110164a9dad8319b1103211573cc87d9daa94120c1083aa325828d99bcd079b771d35b1cdbb2c8a52be5c2dabbb7363c0e5b4b2e0e59699f6221f8565b1faf700b98f63c11581a7ce0036946f760641fbce4e4671cd27b3c6946c15254af122af572604611da246e86ea9d74217d82ebe962b257e472ea27abf873696689bc35bab09ecdecafe9055db6dbe931c5376bd7c42047bd0aaf67407de9c901dc1a57b2d606a042303cb4d0f9dfdf7f13666f9a3cd927a950d5c9564e2e8e4c3ebe4ea5f2df933d0e58fc71496b93cbc736d69388590f16bf3769726801580cd676278237800283972d11e322e87954a42af26917e563b2ca5ab16ec943cd6301d32ea1993630112ff3d02946a0877a2ca44b444f6173358c7f85cd1e65c92dfc07bc4d5c2fd07fea0b319e24cfe455219673a2657c10d1d9cca2606ad0f3d5a42a583a9409bf601ac08b0810d4487d274de0dcbc9f06e7c993d218b5393a01cd439c750c0d42c2e13213538a24144528eb3ea2571036f2d8a131b0ce75022a4d92849247d53e253bc5659272169f814b44b426886b2ff2d8a131b0ce75022a4d92849247d53e253bc5659272169f814b44b426886b2f9daf3d9e051ffbe1630ffc5efb9c0cf030057bb33ce70ad7276a16b86d43784d16ae1850b8b67629fe09e387d9018366cb5a957b5b8201a0e8319b471cc3274bf5ec945e23c62e7f99a3b83b19caffe2900bbf032c49782dd5764e484a83c37000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
-	hexTxHash := "7e466ac297e8a493a4918fdab05e16cd633b0aefb50caea4ef614b92ecb94307"
+	hexWire := "a30800000000000000000000010000000000000000000000b9e6f5c30a0100000001000000520800000100000000000000cc8f1b3e111f4203cb1f38b7d43b14713e59678264179b7c29797ba12daa35570200000000000000010c8088b9e8c9d06915673d4d94fc76348fb7ce7503e8587f30caea67ab8379b815ce6aba274054f337bdd92d9411d8be3f282b05e3c6d42e8eea9f3215b8de33b96a3c7c1dbcb4d8cdd8ef13e50e84cf6480116311677676269d3e662cea608c5a3479e042102a78621252a37f2d99e6824e17a2b11597147d1adf4624e7d436ffffffffffffffff997ebe7877346dc48137c1d115176c60c5dbf0ea77dd8cdca0cfbc0f3d90304ecb5b2b3d60a2b9d4df4a999ef3a768f8bd75c75aac343bff35bed7cfb2e3513315e8ece73c24ca0c97bda403149dcf9fea1c8827b682c1bbe089c8d10355c45e01e549d068cb470cbefe6fddd3b2d8aacfa5a76805e725d5394e882a79d157695ec48dcb7e531ccc3b334ae122d4fd40e242e7d8a85fdb82bd4c9e9621a9a60d042dbbaec8a2acb879b48d311f1264b1aafe6bf26ccc0bb250af7a2e19e8dcdc3851f382c509fb449a701a93c9489ae97bae88feaebe38fc6c128dc4b286724c10ffffffffffffffff14b611da24f94e89dd03121410f05b53c52cfc785da3c8d59bb65d07b78ab0241c6a8f3ffadc251790b9f78a31b82246c883cbfa1330337bd094045c01dcca2a7de1eadf6f1f7116169ed9dd10541a407035bb8fe834a973d8176f51f07a8435fee6a01aa94b675366ed1b054b8091542329dd1538bcec8a7503906281f0b61200ca9a3b000000000200000000000000d85dbd596fc0476c779f3e2e7b5e58b732cb71f9ca056a8828cf845885a22f17848a28b1224942eb4222b7c43fc01e60529c7ee5fab115f3802c91179d0edfa19851d4394c5da06a86f955b2bd1305672e61a9569b5e024f03c957d4160d3d23fad4651d0897d60d89845c58baee90dbb291366e711628910673b9f3eedaaec355d87e2b2619a6809157bf01d3579145794a2b10e5e0f23d053e48a699ad318d80d2e737ca67e32f0848724907f3a847befe125d83031fc249cc24d489bee3cca6dfba0129d5578102c594b72631a13797cc0413391a5a1886c7536e6fdc0c489dfdbc00baba13e05157a7ab7273523dbb98d34c06e3a058424f361aad4a8fbda04b3327dbf973a2fc07d54445ebe6651b2e35a3f5c983dad6f05599505d20e8049ab8b6a8f099304dbc4badb806e2e8b02f90619eacef17710c48c316cddd0889badea8613806d13450208797859e6271335cda185bbfc5844358e701c0ca03ad84e86019661d4b29336d10be7f2d1510cb65478f0ea3e0baea5d49ff962bcccdcf4396a0b3cfed0f1b8c5537b148f88f31e782f30be64807cad8900706b18a31cce9a743694b0abf94d6ff32789e870b3b70970bc2a01b69faea5a6dfc3514b4d6cf831dd715429cb3c9c3c9011422260233eab35f30dec5415fe06f9a22e5e4847cde93f61e896ebeec082ced1e65b7bf5dfe6f6dd064d2649580ae5ec6b09934167cdd0efc24150dee406c18dc4d6def110c74049a3f14c7d2b019606518ab91cba648915908d032c33cd3a6c07bfb908902c5a8bd55ed5fb25582659a9f4fb82aedba03c6946823b020ff8fad039772696c1b58a3434a5c53f5b6670943e90ccf49fb24d88929f467341cd68978082969dfc75ccdf161e1340bb3d66633b52703b2efd6cf769395fa892f5738cf5dee96afe27fe085bed54dd607bc0f0b3fe5fd5e83f1a18ed9e3457ac28bc6a49224c20f17d63fbc38f2d3e49af4f108407a9523e55fc1e89a2c221b0d15a993a3856a9f9618655555f7828734da3193ad2353c81a6f0720e90dbc62a8dcdd1e117b8f6addd574a6c483a5bebb06255e9614ff22ce4ac848de8ee8df47bd133fbd5f46bf9bf9a56e80d6e411cf2803186dad1a7cd9176ba85dff17e29471fb1c6f3a9304630e190406857e511c93711eca6a472f89005ddef430f0df953dcf5a3751bddaf39da32e25a87b1f41cc23f14b25ea9e0289785520696b0a82d6a23a19eb11ca32021c414ba83f0d4012933a4a962826e7185f21f440c8b08c1adf58aec9daee1c8e15e607239e819fc5dea80c697e800a1a18acd235789fb9dfee43f3e8a51ba190656ca8ee9dc7ed1cbfce26a0deb7563f52292f3f6bef6360095b1fa416afa01640ddbabbd3b8fc15223d50c0cdc80cb846947b80408764fab356051d2783e2a9e54917cfaab223c75dd8d5187841fbe93fc79bbc1d63ffffce68ae16c3b4ef3bd92d87bec21f2f958ab4f91535f10c50ef186e3a4d2a43b8060ac15b9ef21256e52123862563540c14d9d0904c20c70d2c5915e352b582f7ee0dfe3338658c1e7245b651428799705d9b76847e9fc8a872ef3aae9c978ca64e3f5f11dd7d49decaad5c299680e7478ddc9651d8578774431b46cc701601af616f9c7323ce76fcd1c6055f7d02652c9a2354ad21ebfd1df37d5254609e3d38666940a2a6dd21c59400bf444f8b297203243de4099b1c8640fb43849f160cdab42a52e0a107df5db400819f7587957f07d72cb498ae97aa6d1e67ae2900ff56f7378f742e04fcdedd2a72ef20aea340f9f65cff2bedc1362733170906a443a1964bdc59c245808014604e2fc9c9f23ecc590da6bedcb81c69ef8f369d69a0c9c663e0faccefde8bf848224166c59b49eb9a58f8fb38bdb42f6b33b5470378bfe21a980b1d78a8da4c32b4f380127bdd6a9c0c96f1b3ee4c0bbc69fa312e7a77560ad2eafdc97017ff9e51da30ee8e2acfaef091236c4c6cf66e2f43129d70744812d2eafdc97017ff9e51da30ee8e2acfaef091236c4c6cf66e2f43129d707448126981ddc905c11356d461b7ccc828dc1ac8e3c92cc9ba3619ee76f9150095a75304d64fd0d2d436f18e6881aae6b7d99bed17078b8f508f0cf4bb2dbd3e7f7871170c739f9d9ea4404bff4066c3ed34d6a52245965b485b766344a380f65e5d2800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+	hexTxHash := "63155db32cdb892e74465950c5fc0ab0e25c218855e141430333cc68cb78e208"
 
 	txHash, err := hex.DecodeString(hexTxHash)
 	if err != nil {
@@ -38,7 +38,7 @@ func TestWireTransaction(t *testing.T) {
 
 	// buffer := bytes.NewBuffer(wire)
 
-	gossip := protocol.NewGossip(protocol.DevNet)
+	gossip := protocol.NewGossip()
 	// frame := gossip.(buffer)
 
 	reader := bytes.NewReader(wire)
@@ -78,7 +78,7 @@ func TestWireTransaction(t *testing.T) {
 	}
 
 	assert.EqualValues(1000000000, decoded.Fee.GasLimit, "unexpected GasLimit")
-	assert.EqualValues(1, decoded.Fee.GasPrice, "unexpected GasLimit")
+	assert.EqualValues(2, decoded.Fee.GasPrice, "unexpected GasPrice")
 
 	hash, err := decoded.Hash(tx.TxType)
 	if err != nil {
diff --git a/pkg/p2p/wire/protocol/frame_test.go b/pkg/p2p/wire/protocol/frame_test.go
index cc7b1143..bd447eae 100644
--- a/pkg/p2p/wire/protocol/frame_test.go
+++ b/pkg/p2p/wire/protocol/frame_test.go
@@ -19,14 +19,14 @@ import (
 func TestWriteReadFrame(t *testing.T) {
 	b := bytes.NewBufferString("pippo")
 	digest := sha3.Sum256(b.Bytes())
-	WriteFrame(b, TestNet, digest[0:checksum.Length])
+	WriteFrame(b, digest[0:checksum.Length])
 
 	length, _ := ReadFrame(b)
 	buf := make([]byte, length)
 	b.Read(buf)
 
-	// Remove magic, checksum and reserved bytes
-	buf = buf[16:]
+	// Remove version, checksum, and reserved bytes
+	buf = buf[(8 + 12):]
 
 	assert.Equal(t, "pippo", string(buf))
 }
diff --git a/pkg/p2p/wire/protocol/gossip_test.go b/pkg/p2p/wire/protocol/gossip_test.go
index 9e5b7d99..d595f327 100644
--- a/pkg/p2p/wire/protocol/gossip_test.go
+++ b/pkg/p2p/wire/protocol/gossip_test.go
@@ -16,7 +16,7 @@ import (
 )
 
 func TestProcess(t *testing.T) {
-	g := protocol.NewGossip(protocol.DevNet)
+	g := protocol.NewGossip()
 
 	m := bytes.NewBufferString("pippo")
 
@@ -36,15 +36,15 @@ func TestProcess(t *testing.T) {
 
 	buf := new(bytes.Buffer)
 	_, _ = buf.Write([]byte("pippo"))
-	// First 16 bytes of `msg` are the magic, checksum and reserved bytes
-	assert.Equal(t, buf.Bytes(), msg[16:])
+	// First 20 bytes of `msg` are the version, checksum, and reserved bytes
+	assert.Equal(t, buf.Bytes(), msg[(8+12):])
 }
 
 func TestUnpackLength(t *testing.T) {
 	test := "pippo"
 	b := bytes.NewBufferString(test)
 
-	g := protocol.NewGossip(protocol.DevNet)
+	g := protocol.NewGossip()
 	assert.NoError(t, g.Process(b))
 
 	length, err := g.UnpackLength(b)
diff --git a/pkg/p2p/wire/protocol/protocol_test.go b/pkg/p2p/wire/protocol/protocol_test.go
index 1e90c682..6034dd5c 100644
--- a/pkg/p2p/wire/protocol/protocol_test.go
+++ b/pkg/p2p/wire/protocol/protocol_test.go
@@ -7,39 +7,14 @@
 package protocol_test
 
 import (
-	"bytes"
 	"io"
 	"net"
 	"testing"
 	"time"
 
-	"github.com/dusk-network/dusk-blockchain/pkg/p2p/wire/protocol"
 	"github.com/stretchr/testify/assert"
 )
 
-var magicTest = []struct {
-	magic   protocol.Magic
-	payload []byte
-}{
-	{protocol.TestNet, []byte("pippo")},
-	{protocol.DevNet, []byte("paperino")},
-	{protocol.TestNet, []byte("pluto")},
-	{protocol.MainNet, []byte("bruto")},
-}
-
-func TestExtract(t *testing.T) {
-	var buf bytes.Buffer
-
-	for _, tt := range magicTest {
-		buf = tt.magic.ToBuffer()
-		buf.ReadFrom(bytes.NewBuffer(tt.payload))
-		magic, err := protocol.Extract(&buf)
-		assert.Equal(t, magic, tt.magic)
-		assert.NoError(t, err)
-		assert.Equal(t, tt.payload, buf.Bytes())
-	}
-}
-
 // Ensure that a simple `Read` call from a net.Conn can result in a short read, and
 // that use of `io.ReadFull` is preferred.
 func TestShortRead(t *testing.T) {