pkg: hide it by moving to _pkg.dev
The idea here is to preserve the history of `dev` branch development and its code when merging with the `master`. Later this code could be moved into the masters code where appropriate.
This commit is contained in:
parent
bb2568cc53
commit
ddd1d92ff1
183 changed files with 0 additions and 0 deletions
156
_pkg.dev/wire/message.go
Normal file
156
_pkg.dev/wire/message.go
Normal file
|
@ -0,0 +1,156 @@
|
|||
package wire
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
|
||||
checksum "github.com/CityOfZion/neo-go/pkg/wire/util/Checksum"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||
"github.com/CityOfZion/neo-go/pkg/wire/payload"
|
||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||
)
|
||||
|
||||
// Messager is implemented by any object that can
|
||||
// Encode and Decode Payloads
|
||||
type Messager interface {
|
||||
// EncodePayload takes a message payload and encodes it
|
||||
EncodePayload(w io.Writer) error
|
||||
// DecodePayload takes an io.Reader and decodes it into
|
||||
// a message payload
|
||||
DecodePayload(r io.Reader) error
|
||||
// Command returns the assosciated command type
|
||||
Command() command.Type
|
||||
}
|
||||
|
||||
const (
|
||||
// Magic + cmd + length + checksum
|
||||
minMsgSize = 4 + 12 + 4 + 4
|
||||
)
|
||||
|
||||
var (
|
||||
errChecksumMismatch = errors.New("checksum mismatch")
|
||||
)
|
||||
|
||||
// WriteMessage will write a message to a given io.Writer
|
||||
func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
|
||||
bw := &util.BinWriter{W: w}
|
||||
bw.Write(magic)
|
||||
bw.Write(cmdToByteArray(message.Command()))
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := message.EncodePayload(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payloadLen := util.BufferLength(buf)
|
||||
checksum := checksum.FromBytes(buf.Bytes())
|
||||
|
||||
bw.Write(payloadLen)
|
||||
bw.Write(checksum)
|
||||
|
||||
bw.WriteBigEnd(buf.Bytes())
|
||||
|
||||
return bw.Err
|
||||
}
|
||||
|
||||
// ReadMessage will read a message from a given io.Reader
|
||||
func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
|
||||
|
||||
byt := make([]byte, minMsgSize)
|
||||
|
||||
if _, err := io.ReadFull(r, byt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader := bytes.NewReader(byt)
|
||||
|
||||
var header Base
|
||||
_, err := header.DecodeBase(reader)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Error decoding into the header base")
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
_, err = io.CopyN(buf, r, int64(header.PayloadLength))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compare the checksum of the payload.
|
||||
if !checksum.Compare(header.Checksum, buf.Bytes()) {
|
||||
return nil, errChecksumMismatch
|
||||
}
|
||||
switch header.CMD {
|
||||
case command.Version:
|
||||
v := &payload.VersionMessage{}
|
||||
err := v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.Verack:
|
||||
v, err := payload.NewVerackMessage()
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.Inv:
|
||||
v, err := payload.NewInvMessage(0)
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.GetAddr:
|
||||
v, err := payload.NewGetAddrMessage()
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.Addr:
|
||||
v, err := payload.NewAddrMessage()
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.Block:
|
||||
v, err := payload.NewBlockMessage()
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.GetBlocks:
|
||||
v, err := payload.NewGetBlocksMessage([]util.Uint256{}, util.Uint256{})
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.GetData:
|
||||
v, err := payload.NewGetDataMessage(payload.InvTypeTx)
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.GetHeaders:
|
||||
v, err := payload.NewGetHeadersMessage([]util.Uint256{}, util.Uint256{})
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.Headers:
|
||||
v, err := payload.NewHeadersMessage()
|
||||
err = v.DecodePayload(buf)
|
||||
return v, err
|
||||
case command.TX:
|
||||
reader := bufio.NewReader(buf)
|
||||
tx, err := transaction.FromReader(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload.NewTXMessage(tx)
|
||||
}
|
||||
return nil, errors.New("Unknown Message found")
|
||||
|
||||
}
|
||||
|
||||
func cmdToByteArray(cmd command.Type) [command.Size]byte {
|
||||
cmdLen := len(cmd)
|
||||
if cmdLen > command.Size {
|
||||
panic("exceeded command max length of size 12")
|
||||
}
|
||||
|
||||
// The command can have max 12 bytes, rest is filled with 0.
|
||||
b := [command.Size]byte{}
|
||||
for i := 0; i < cmdLen; i++ {
|
||||
b[i] = cmd[i]
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue