Merge pull request #328 from nspcc-dev/drop-redundant-dev-code-part-4

Drop redundant dev code part 4.

The next one in series of #315, #318 and #322. Continuing with #307. Fixes #173 along the way.
This commit is contained in:
Roman Khimov 2019-08-30 15:43:18 +03:00 committed by GitHub
commit d0c39a561c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 360 additions and 1492 deletions

View file

@ -1,67 +0,0 @@
package payload
import (
"bufio"
"bytes"
"io"
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Block representa a Block in the neo-network
type Block struct {
BlockBase
Txs []transaction.Transactioner
}
// Decode decodes an io.Reader into a Block
func (b *Block) Decode(r io.Reader) error {
br := &util.BinReader{R: r}
b.DecodePayload(br)
return br.Err
}
// Encode writes a block into a io.Writer
func (b *Block) Encode(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.EncodePayload(bw)
return bw.Err
}
//EncodePayload implements Messager interface
func (b *Block) EncodePayload(bw *util.BinWriter) {
b.BlockBase.EncodePayload(bw)
bw.VarUint(uint64(len(b.Txs)))
for _, tx := range b.Txs {
tx.Encode(bw.W)
}
}
// DecodePayload implements Messager interface
func (b *Block) DecodePayload(br *util.BinReader) error {
b.BlockBase.DecodePayload(br)
lenTXs := br.VarUint()
b.Txs = make([]transaction.Transactioner, lenTXs)
reader := bufio.NewReader(br.R)
for i := 0; i < int(lenTXs); i++ {
tx, err := transaction.FromReader(reader)
if err != nil {
return err
}
b.Txs[i] = tx
}
return nil
}
// Bytes returns the Byte representation of Block
func (b *Block) Bytes() ([]byte, error) {
buf := new(bytes.Buffer)
err := b.Encode(buf)
return buf.Bytes(), err
}

File diff suppressed because one or more lines are too long

View file

@ -1,132 +0,0 @@
package payload
import (
"bytes"
"errors"
"io"
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
var (
errPadding = errors.New("There is a padding mismatch")
)
//BlockBase represents the base of the block
// This is different than the block header. See HeadersMessage
type BlockBase struct {
// Version of the block.
Version uint32 `json:"version"`
// hash of the previous block.
PrevHash util.Uint256 `json:"previousblockhash"`
// Root hash of a transaction list.
MerkleRoot util.Uint256 `json:"merkleroot"`
// The time stamp of each block must be later than previous block's time stamp.
// Generally the difference of two block's time stamp is about 15 seconds and imprecision is allowed.
// The height of the block must be exactly equal to the height of the previous block plus 1.
Timestamp uint32 `json:"time"`
// index/height of the block
Index uint32 `json:"height"`
// Random number also called nonce
ConsensusData uint64 `json:"nonce"`
// Contract addresss of the next miner
NextConsensus util.Uint160 `json:"next_consensus"`
// Padding that is fixed to 1
_ uint8
// Script used to validate the block
Witness transaction.Witness `json:"script"`
// hash of this block, created when binary encoded.
Hash util.Uint256
}
// EncodePayload implements the Messager interface
func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
b.encodeHashableFields(bw)
bw.Write(uint8(1))
b.Witness.Encode(bw)
return bw.Err
}
// Decode decodes an io.Reader into a Blockbase
func (b *BlockBase) Decode(r io.Reader) error {
br := &util.BinReader{R: r}
b.DecodePayload(br)
return br.Err
}
// Encode encodes a blockbase into an io.Writer
func (b *BlockBase) Encode(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.EncodePayload(bw)
return bw.Err
}
func (b *BlockBase) encodeHashableFields(bw *util.BinWriter) {
bw.Write(b.Version)
bw.Write(b.PrevHash)
bw.Write(b.MerkleRoot)
bw.Write(b.Timestamp)
bw.Write(b.Index)
bw.Write(b.ConsensusData)
bw.Write(b.NextConsensus)
}
// DecodePayload implements the messager interface
func (b *BlockBase) DecodePayload(br *util.BinReader) error {
b.decodeHashableFields(br)
var padding uint8
br.Read(&padding)
if padding != 1 {
return errPadding
}
b.Witness = transaction.Witness{}
b.Witness.Decode(br)
err := b.createHash()
if err != nil {
return err
}
return br.Err
}
func (b *BlockBase) decodeHashableFields(br *util.BinReader) {
br.Read(&b.Version)
br.Read(&b.PrevHash)
br.Read(&b.MerkleRoot)
br.Read(&b.Timestamp)
br.Read(&b.Index)
br.Read(&b.ConsensusData)
br.Read(&b.NextConsensus)
}
func (b *BlockBase) createHash() error {
hash, err := util.CalculateHash(b.encodeHashableFields)
b.Hash = hash
return err
}
// Bytes returns the byte representation of Blockbase
func (b *BlockBase) Bytes() ([]byte, error) {
buf := new(bytes.Buffer)
err := b.Encode(buf)
return buf.Bytes(), err
}

View file

@ -1,8 +0,0 @@
package payload
import "testing"
func Test(t *testing.T) {
//tests for this have been included in the mheaders_test file
}

View file

@ -1,64 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// AddrMessage represents an address message on the neo network
type AddrMessage struct {
AddrList []*NetAddr
}
// NewAddrMessage instantiates a new AddrMessage
func NewAddrMessage() (*AddrMessage, error) {
addrMess := &AddrMessage{
nil,
}
return addrMess, nil
}
// AddNetAddr will add a net address into the Address message
func (a *AddrMessage) AddNetAddr(n *NetAddr) error {
a.AddrList = append(a.AddrList, n)
// TODO:check if max reached, if so return err. What is max?
return nil
}
// DecodePayload Implements Messager interface
func (a *AddrMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
listLen := br.VarUint()
a.AddrList = make([]*NetAddr, listLen)
for i := 0; i < int(listLen); i++ {
a.AddrList[i] = &NetAddr{}
a.AddrList[i].DecodePayload(br)
if br.Err != nil {
return br.Err
}
}
return br.Err
}
// EncodePayload Implements messager interface
func (a *AddrMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
listLen := uint64(len(a.AddrList))
bw.VarUint(listLen)
for _, addr := range a.AddrList {
addr.EncodePayload(bw)
}
return bw.Err
}
// Command Implements messager interface
func (a *AddrMessage) Command() command.Type {
return command.Addr
}

View file

@ -1,40 +0,0 @@
package payload
import (
"bytes"
"net"
"testing"
"time"
"github.com/CityOfZion/neo-go/pkg/wire/util/Checksum"
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
"github.com/stretchr/testify/assert"
)
func TestAddrMessageEncodeDecode(t *testing.T) {
ip := []byte(net.ParseIP("127.0.0.1").To16())
var ipByte [16]byte
copy(ipByte[:], ip)
netaddr, err := NewNetAddr(uint32(time.Now().Unix()), ipByte, 8080, protocol.NodePeerService)
addrmsg, err := NewAddrMessage()
addrmsg.AddNetAddr(netaddr)
buf := new(bytes.Buffer)
err = addrmsg.EncodePayload(buf)
expected := checksum.FromBuf(buf)
addrmsgDec, err := NewAddrMessage()
r := bytes.NewReader(buf.Bytes())
err = addrmsgDec.DecodePayload(r)
buf = new(bytes.Buffer)
err = addrmsgDec.EncodePayload(buf)
have := checksum.FromBuf(buf)
assert.Equal(t, nil, err)
assert.Equal(t, expected, have)
}

View file

@ -1,38 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// BlockMessage represents a block message on the neo-network
type BlockMessage struct {
Block
}
// NewBlockMessage will return a block message object
func NewBlockMessage() (*BlockMessage, error) {
return &BlockMessage{}, nil
}
// DecodePayload Implements Messager interface
func (b *BlockMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
b.Block.DecodePayload(br)
return br.Err
}
// EncodePayload Implements messager interface
func (b *BlockMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.Block.EncodePayload(bw)
return bw.Err
}
// Command Implements messager interface
func (b *BlockMessage) Command() command.Type {
return command.Block
}

View file

@ -1,30 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
//GetAddrMessage represents a GetAddress message on the neo-network
type GetAddrMessage struct{}
// NewGetAddrMessage returns a GetAddrMessage object
func NewGetAddrMessage() (*GetAddrMessage, error) {
return &GetAddrMessage{}, nil
}
// DecodePayload Implements Messager interface
func (v *GetAddrMessage) DecodePayload(r io.Reader) error {
return nil
}
// EncodePayload Implements messager interface
func (v *GetAddrMessage) EncodePayload(w io.Writer) error {
return nil
}
// Command Implements messager interface
func (v *GetAddrMessage) Command() command.Type {
return command.GetAddr
}

View file

@ -1,24 +0,0 @@
package payload
import (
"bytes"
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/util/Checksum"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/stretchr/testify/assert"
)
func TestNewGetAddr(t *testing.T) {
getAddrMessage, err := NewGetAddrMessage()
assert.Equal(t, nil, err)
assert.Equal(t, command.GetAddr, getAddrMessage.Command())
buf := new(bytes.Buffer)
assert.Equal(t, int(3806393949), int(checksum.FromBuf(buf)))
assert.Equal(t, int(0), len(buf.Bytes()))
}

View file

@ -1,24 +0,0 @@
package payload
import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// GetBlocksMessage represnts a GetBlocks message on the neo-network
type GetBlocksMessage struct {
*GetHeadersMessage
}
// NewGetBlocksMessage returns a GetBlocksMessage object
func NewGetBlocksMessage(start []util.Uint256, stop util.Uint256) (*GetBlocksMessage, error) {
GetHeaders, err := newAbstractGetHeaders(start, stop, command.GetBlocks)
if err != nil {
return nil, err
}
return &GetBlocksMessage{
GetHeaders,
}, nil
}

View file

@ -1,27 +0,0 @@
package payload
import (
"crypto/sha256"
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"github.com/stretchr/testify/assert"
)
func TestGetBlocksCommandType(t *testing.T) {
var (
start = []util.Uint256{
sha256.Sum256([]byte("a")),
sha256.Sum256([]byte("b")),
sha256.Sum256([]byte("c")),
sha256.Sum256([]byte("d")),
}
stop = sha256.Sum256([]byte("e"))
)
getBlocks, err := NewGetBlocksMessage(start, stop)
assert.Equal(t, err, nil)
assert.Equal(t, command.GetBlocks, getBlocks.Command())
}

View file

@ -1,18 +0,0 @@
package payload
import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// GetDataMessage represents a GetData message on the neo-network
type GetDataMessage struct {
*InvMessage
}
//NewGetDataMessage returns a GetDataMessage object
func NewGetDataMessage(typ InvType) (*GetDataMessage, error) {
getData, err := newAbstractInv(typ, command.GetData)
return &GetDataMessage{
getData,
}, err
}

View file

@ -1,19 +0,0 @@
package payload
import (
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/stretchr/testify/assert"
)
func TestGetDataCommandType(t *testing.T) {
getData, err := NewGetDataMessage(InvTypeBlock)
assert.Equal(t, err, nil)
assert.Equal(t, command.GetData, getData.Command())
}
func TestOtherFunctions(t *testing.T) {
// Other capabilities are tested in the inherited struct
}

View file

@ -1,61 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//GetHeadersMessage represents a GetHeaders message on the neo-network
type GetHeadersMessage struct {
cmd command.Type
hashStart []util.Uint256
hashStop util.Uint256
}
// NewGetHeadersMessage returns a NewGetHeaders object
// Start contains the list of all headers you want to fetch
// End contains the list of the highest header hash you would like to fetch
func NewGetHeadersMessage(start []util.Uint256, stop util.Uint256) (*GetHeadersMessage, error) {
getHeaders := &GetHeadersMessage{command.GetHeaders, start, stop}
return getHeaders, nil
}
func newAbstractGetHeaders(start []util.Uint256, stop util.Uint256, cmd command.Type) (*GetHeadersMessage, error) {
getHeaders, err := NewGetHeadersMessage(start, stop)
if err != nil {
return nil, err
}
getHeaders.cmd = cmd
return getHeaders, nil
}
// DecodePayload Implements Messager interface
func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
br := util.BinReader{R: r}
lenStart := br.VarUint()
v.hashStart = make([]util.Uint256, lenStart)
br.Read(&v.hashStart)
br.Read(&v.hashStop)
return br.Err
}
// EncodePayload Implements messager interface
func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.VarUint(uint64(len(v.hashStart)))
bw.Write(v.hashStart)
bw.Write(v.hashStop)
return bw.Err
}
// Command Implements messager interface
func (v *GetHeadersMessage) Command() command.Type {
return v.cmd
}

View file

@ -1,47 +0,0 @@
package payload
import (
"bytes"
"crypto/sha256"
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/util/Checksum"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"github.com/stretchr/testify/assert"
)
// Test taken from neo-go v1
func TestGetHeadersEncodeDecode(t *testing.T) {
var (
start = []util.Uint256{
sha256.Sum256([]byte("a")),
sha256.Sum256([]byte("b")),
sha256.Sum256([]byte("c")),
sha256.Sum256([]byte("d")),
}
stop = sha256.Sum256([]byte("e"))
)
msgGetHeaders, err := NewGetHeadersMessage(start, stop)
assert.Equal(t, nil, err)
buf := new(bytes.Buffer)
err = msgGetHeaders.EncodePayload(buf)
assert.Equal(t, nil, err)
expected := checksum.FromBuf(buf)
msgGetHeadersDec, err := NewGetHeadersMessage([]util.Uint256{}, util.Uint256{})
assert.Equal(t, nil, err)
r := bytes.NewReader(buf.Bytes())
err = msgGetHeadersDec.DecodePayload(r)
assert.Equal(t, nil, err)
buf = new(bytes.Buffer)
err = msgGetHeadersDec.EncodePayload(buf)
have := checksum.FromBuf(buf)
assert.Equal(t, expected, have)
}

View file

@ -1,82 +0,0 @@
package payload
import (
"errors"
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// HeadersMessage represents a Header(s) Message on the neo-network
type HeadersMessage struct {
Headers []*BlockBase
// Padding that is fixed to 0
_ uint8
}
// Users can at most request 2k header
const (
maxHeadersAllowed = 2000
)
var (
errMaxHeaders = errors.New("Maximum amount of headers allowed is 2000")
)
//NewHeadersMessage returns a HeadersMessage Object
func NewHeadersMessage() (*HeadersMessage, error) {
headers := &HeadersMessage{nil, 0}
return headers, nil
}
// AddHeader adds a header into the list of Headers.
// Since a header is just blockbase with padding, we use BlockBase
func (h *HeadersMessage) AddHeader(head *BlockBase) error {
if len(h.Headers)+1 > maxHeadersAllowed {
return errMaxHeaders
}
h.Headers = append(h.Headers, head)
return nil
}
// DecodePayload Implements Messager interface
func (h *HeadersMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
lenHeaders := br.VarUint()
h.Headers = make([]*BlockBase, lenHeaders)
for i := 0; i < int(lenHeaders); i++ {
header := &BlockBase{}
header.DecodePayload(br)
var padding uint8
br.Read(&padding)
if padding != 0 {
return errPadding
}
h.Headers[i] = header
}
return br.Err
}
// EncodePayload Implements messager interface
func (h *HeadersMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.VarUint(uint64(len(h.Headers)))
for _, header := range h.Headers {
header.EncodePayload(bw)
bw.Write(uint8(0))
}
return bw.Err
}
// Command Implements messager interface
func (h *HeadersMessage) Command() command.Type {
return command.Headers
}

View file

@ -1,82 +0,0 @@
package payload
import (
"bytes"
"encoding/hex"
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"github.com/CityOfZion/neo-go/pkg/wire/util/address"
"github.com/stretchr/testify/assert"
)
func TestNewHeaderMessage(t *testing.T) {
msgHeaders, err := NewHeadersMessage()
assert.Equal(t, nil, err)
assert.Equal(t, 0, len(msgHeaders.Headers))
}
func TestAddAndEncodeHeaders(t *testing.T) {
// uses block10 from mainnet
msgHeaders, _ := NewHeadersMessage()
prevH, _ := util.Uint256DecodeString("005fb74a6de169ce5daf59a114405e5b27238b2489690e3b2a60c14ddfc3b326")
merkleRoot, _ := util.Uint256DecodeString("ca6d58bcb837472c2f77877e68495b83fd5b714dfe0c8230a525f4511a3239f4")
invocationScript, _ := hex.DecodeString("4036fdd23248880c1c311bcd97df04fe6d740dc1bf340c26915f0466e31e81c039012eca7a760270389e04b58b99820fe49cf8c24c9afc65d696b4d3f406a1e6b5405172a9b461e68dd399c8716de11d31f7dd2ec3be327c636b024562db6ac5df1cffdbee74c994736fd49803234d2baffbc0054f28ba5ec76494a467b4106955bb4084af7746d269241628c667003e9d39288b190ad5cef218ada625cbba8be411bb153828d8d3634e8f586638e2448425bc5b671be69800392ccbdebc945a5099c7406f6a11824105ecad345e525957053e77fbc0119d6b3fa7f854527e816cfce0d95dac66888e07e8990c95103d8e46124aac16f152e088520d7ec8325e3a2456f840e5b77ef0e3c410b347ccaf8a87516d10b88d436563c80712153273993afc320ec49b638225f58de464a1345e62a564b398939f96f6f4b7cf21b583609f85495a")
verificationScript, _ := hex.DecodeString("552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae")
nextCon, _ := util.Uint160DecodeString(address.ToScriptHash("APyEx5f4Zm4oCHwFWiSTaph1fPBxZacYVR"))
msgHeaders.AddHeader(&BlockBase{
Version: 0,
Index: 10,
PrevHash: prevH.Reverse(),
MerkleRoot: merkleRoot.Reverse(),
Timestamp: 1476647551,
ConsensusData: 0xc0f0280216ff14bf,
NextConsensus: nextCon,
Witness: transaction.Witness{
InvocationScript: invocationScript,
VerificationScript: verificationScript,
},
})
assert.Equal(t, 1, len(msgHeaders.Headers))
err := msgHeaders.Headers[0].createHash()
assert.Equal(t, nil, err)
// Hash being correct, automatically verifies that the fields are encoded properly
assert.Equal(t, "f3c4ec44c07eccbda974f1ee34bc6654ab6d3f22cd89c2e5c593a16d6cc7e6e8", msgHeaders.Headers[0].Hash.ReverseString())
}
func TestEncodeDecode(t *testing.T) {
rawBlockHeaders := "010000000026b3c3df4dc1602a3b0e6989248b23275b5e4014a159af5dce69e16d4ab75f00f439321a51f425a530820cfe4d715bfd835b49687e87772f2c4737b8bc586dca7fda03580a000000bf14ff160228f0c059e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd45014036fdd23248880c1c311bcd97df04fe6d740dc1bf340c26915f0466e31e81c039012eca7a760270389e04b58b99820fe49cf8c24c9afc65d696b4d3f406a1e6b5405172a9b461e68dd399c8716de11d31f7dd2ec3be327c636b024562db6ac5df1cffdbee74c994736fd49803234d2baffbc0054f28ba5ec76494a467b4106955bb4084af7746d269241628c667003e9d39288b190ad5cef218ada625cbba8be411bb153828d8d3634e8f586638e2448425bc5b671be69800392ccbdebc945a5099c7406f6a11824105ecad345e525957053e77fbc0119d6b3fa7f854527e816cfce0d95dac66888e07e8990c95103d8e46124aac16f152e088520d7ec8325e3a2456f840e5b77ef0e3c410b347ccaf8a87516d10b88d436563c80712153273993afc320ec49b638225f58de464a1345e62a564b398939f96f6f4b7cf21b583609f85495af1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae00"
var headerMsg HeadersMessage
rawBlockBytes, _ := hex.DecodeString(rawBlockHeaders)
r := bytes.NewReader(rawBlockBytes)
err := headerMsg.DecodePayload(r)
assert.Equal(t, 1, len(headerMsg.Headers))
header := headerMsg.Headers[0]
err = header.createHash()
assert.Equal(t, "f3c4ec44c07eccbda974f1ee34bc6654ab6d3f22cd89c2e5c593a16d6cc7e6e8", header.Hash.ReverseString())
buf := new(bytes.Buffer)
err = headerMsg.EncodePayload(buf)
assert.Equal(t, nil, err)
assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(buf.Bytes()))
}

View file

@ -1,114 +0,0 @@
package payload
import (
"errors"
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//InvType represents the enum of inventory types
type InvType uint8
const (
// InvTypeTx represents the transaction inventory type
InvTypeTx InvType = 0x01
// InvTypeBlock represents the block inventory type
InvTypeBlock InvType = 0x02
// InvTypeConsensus represents the consensus inventory type
InvTypeConsensus InvType = 0xe0
)
const maxHashes = 0x10000000
var errMaxHash = errors.New("max size For Hashes reached")
// InvMessage represents an Inventory message on the neo-network
type InvMessage struct {
cmd command.Type
Type InvType
Hashes []util.Uint256
}
//NewInvMessage returns an InvMessage object
func NewInvMessage(typ InvType) (*InvMessage, error) {
inv := &InvMessage{
command.Inv,
typ,
nil,
}
return inv, nil
}
func newAbstractInv(typ InvType, cmd command.Type) (*InvMessage, error) {
inv, err := NewInvMessage(typ)
if err != nil {
return nil, err
}
inv.cmd = cmd
return inv, nil
}
// AddHash adds a hash to the list of hashes
func (inv *InvMessage) AddHash(h util.Uint256) error {
if len(inv.Hashes)+1 > maxHashes {
return errMaxHash
}
inv.Hashes = append(inv.Hashes, h)
return nil
}
// AddHashes adds multiple hashes to the list of hashes
func (inv *InvMessage) AddHashes(hashes []util.Uint256) error {
var err error
for _, hash := range hashes {
err = inv.AddHash(hash)
if err != nil {
break
}
}
return err
}
// DecodePayload Implements Messager interface
func (inv *InvMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
br.Read(&inv.Type)
listLen := br.VarUint()
inv.Hashes = make([]util.Uint256, listLen)
for i := 0; i < int(listLen); i++ {
br.Read(&inv.Hashes[i])
}
return nil
}
// EncodePayload Implements messager interface
func (inv *InvMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.Write(inv.Type)
lenhashes := len(inv.Hashes)
bw.VarUint(uint64(lenhashes))
for _, hash := range inv.Hashes {
bw.Write(hash)
}
return bw.Err
}
// Command Implements messager interface
func (inv *InvMessage) Command() command.Type {
return inv.cmd
}

View file

@ -1,78 +0,0 @@
package payload
import (
"bytes"
"encoding/hex"
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"github.com/stretchr/testify/assert"
)
func TestNewInventory(t *testing.T) {
msgInv, err := NewInvMessage(InvTypeBlock)
assert.Equal(t, nil, err)
assert.Equal(t, command.Inv, msgInv.Command())
hash, _ := util.Uint256DecodeBytes([]byte("hello"))
err = msgInv.AddHash(hash)
assert.Equal(t, nil, err)
}
// Adjust test time or it will timeout
// func TestMaxHashes(t *testing.T) {
// msgInv, err := NewInvMessage(InvTypeBlock)
// assert.Equal(t, nil, err)
// hash, _ := util.Uint256DecodeBytes([]byte("hello"))
// for i := 0; i <= maxHashes+1; i++ {
// err = msgInv.AddHash(hash)
// }
// if err == nil {
// assert.Fail(t, "Max Hashes Exceeded, only allowed %v but have %v", maxHashes, len(msgInv.Hashes))
// } else if err != MaxHashError {
// assert.Fail(t, "Expected a MaxHashError, however we got %s", err.Error())
// }
// }
func TestEncodeDecodePayload(t *testing.T) {
msgInv, err := NewInvMessage(InvTypeBlock)
assert.Equal(t, nil, err)
blockOneHash := "d782db8a38b0eea0d7394e0f007c61c71798867578c77c387c08113903946cc9"
hash, _ := util.Uint256DecodeString(blockOneHash)
err = msgInv.AddHash(hash)
assert.Equal(t, nil, err)
buf := new(bytes.Buffer)
err = msgInv.EncodePayload(buf)
assert.Equal(t, nil, err)
numOfHashes := []byte{1}
expected := append([]byte{uint8(InvTypeBlock)}, numOfHashes...)
expected = append(expected, hash.Bytes()...)
assert.Equal(t, hex.EncodeToString(expected), hex.EncodeToString(buf.Bytes()))
var InvDec InvMessage
r := bytes.NewReader(buf.Bytes())
err = InvDec.DecodePayload(r)
assert.Equal(t, nil, err)
assert.Equal(t, 1, len(InvDec.Hashes))
assert.Equal(t, blockOneHash, hex.EncodeToString(InvDec.Hashes[0].Bytes()))
}
func TestEmptyInv(t *testing.T) {
msgInv, err := NewInvMessage(InvTypeBlock)
assert.Equal(t, nil, err)
buf := new(bytes.Buffer)
msgInv.EncodePayload(buf)
assert.Equal(t, []byte{byte(InvTypeBlock), 0}, buf.Bytes())
assert.Equal(t, 0, len(msgInv.Hashes))
}

View file

@ -1,30 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// GetMempool represents a GetMempool message on the neo-network
type GetMempool struct{}
//NewGetMempool returns a GetMempool message
func NewGetMempool() (*GetMempool, error) {
return &GetMempool{}, nil
}
// DecodePayload Implements Messager interface
func (v *GetMempool) DecodePayload(r io.Reader) error {
return nil
}
// EncodePayload Implements messager interface
func (v *GetMempool) EncodePayload(w io.Writer) error {
return nil
}
// Command Implements messager interface
func (v *GetMempool) Command() command.Type {
return command.Mempool
}

View file

@ -1,30 +0,0 @@
package payload
import (
"io"
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
//VerackMessage represents a verack message on the neo-network
type VerackMessage struct{}
//NewVerackMessage returns a verack message
func NewVerackMessage() (*VerackMessage, error) {
return &VerackMessage{}, nil
}
// DecodePayload Implements Messager interface
func (v *VerackMessage) DecodePayload(r io.Reader) error {
return nil
}
// EncodePayload Implements messager interface
func (v *VerackMessage) EncodePayload(w io.Writer) error {
return nil
}
// Command Implements messager interface
func (v *VerackMessage) Command() command.Type {
return command.Verack
}

View file

@ -1,17 +0,0 @@
package payload
import (
"testing"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/stretchr/testify/assert"
)
func TestNewVerack(t *testing.T) {
verackMessage, err := NewVerackMessage()
assert.Equal(t, nil, err)
assert.Equal(t, command.Verack, verackMessage.Command())
}

View file

@ -1,93 +0,0 @@
// Copied and Modified for NEO from: https://github.com/decred/dcrd/blob/master/wire/VersionMessage.go
package payload
import (
"errors"
"io"
"net"
"time"
"github.com/CityOfZion/neo-go/pkg/wire/command"
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
const minMsgVersionSize = 28
var errInvalidNetAddr = errors.New("provided net.Addr is not a net.TCPAddr")
//VersionMessage represents a version message on the neo-network
type VersionMessage struct {
Version protocol.Version
Timestamp uint32
Services protocol.ServiceFlag
IP net.IP
Port uint16
Nonce uint32
UserAgent []byte
StartHeight uint32
Relay bool
}
//NewVersionMessage will return a VersionMessage object
func NewVersionMessage(addr net.Addr, startHeight uint32, relay bool, pver protocol.Version, userAgent string, nonce uint32, services protocol.ServiceFlag) (*VersionMessage, error) {
tcpAddr, ok := addr.(*net.TCPAddr)
if !ok {
return nil, errInvalidNetAddr
}
version := &VersionMessage{
pver,
uint32(time.Now().Unix()),
services,
tcpAddr.IP,
uint16(tcpAddr.Port),
nonce,
[]byte(userAgent),
startHeight,
relay,
}
return version, nil
}
// DecodePayload Implements Messager interface
func (v *VersionMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
br.Read(&v.Version)
br.Read(&v.Services)
br.Read(&v.Timestamp)
br.Read(&v.Port) // Port is not BigEndian as stated in the docs
br.Read(&v.Nonce)
var lenUA uint8
br.Read(&lenUA)
v.UserAgent = make([]byte, lenUA)
br.Read(&v.UserAgent)
br.Read(&v.StartHeight)
br.Read(&v.Relay)
return br.Err
}
// EncodePayload Implements messager interface
func (v *VersionMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.Write(v.Version)
bw.Write(v.Services)
bw.Write(v.Timestamp)
bw.Write(v.Port) // Not big End
bw.Write(v.Nonce)
bw.Write(uint8(len(v.UserAgent)))
bw.Write(v.UserAgent)
bw.Write(v.StartHeight)
bw.Write(v.Relay)
return bw.Err
}
// Command Implements messager interface
func (v *VersionMessage) Command() command.Type {
return command.Version
}

View file

@ -1,59 +0,0 @@
package payload
import (
"bytes"
"math/rand"
"net"
"testing"
"time"
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
"github.com/stretchr/testify/assert"
)
func TestValidNewVersionMessage(t *testing.T) {
expectedIP := "127.0.0.1"
expectedPort := 8333
tcpAddrMe := &net.TCPAddr{IP: net.ParseIP(expectedIP), Port: expectedPort}
nonce := randRange(12949672, 42949672)
message, err := NewVersionMessage(tcpAddrMe, 0, true, protocol.DefaultVersion, protocol.UserAgent, nonce, protocol.NodePeerService)
assert.Equal(t, nil, err)
assert.Equal(t, expectedIP, message.IP.String())
assert.Equal(t, uint16(expectedPort), message.Port)
assert.Equal(t, protocol.DefaultVersion, message.Version)
}
func TestEncode(t *testing.T) {
expectedIP := "127.0.0.1"
expectedPort := 8333
tcpAddrMe := &net.TCPAddr{IP: net.ParseIP(expectedIP), Port: expectedPort}
nonce := randRange(12949672, 42949672)
message, err := NewVersionMessage(tcpAddrMe, 0, true, protocol.DefaultVersion, protocol.UserAgent, nonce, protocol.NodePeerService)
buf := new(bytes.Buffer)
err = message.EncodePayload(buf)
assert.Equal(t, nil, err)
assert.Equal(t, len(message.UserAgent)+minMsgVersionSize, int(buf.Len()))
}
func TestLenIsCorrect(t *testing.T) {
expectedIP := "127.0.0.1"
expectedPort := 8333
tcpAddrMe := &net.TCPAddr{IP: net.ParseIP(expectedIP), Port: expectedPort}
nonce := randRange(12949672, 42949672)
message, err := NewVersionMessage(tcpAddrMe, 0, true, protocol.DefaultVersion, protocol.UserAgent, nonce, protocol.NodePeerService)
buf := new(bytes.Buffer)
err = message.EncodePayload(buf)
assert.Equal(t, nil, err)
assert.Equal(t, len(message.UserAgent)+minMsgVersionSize, len(buf.Bytes()))
}
func randRange(min, max int) uint32 {
rand.Seed(time.Now().Unix() + int64(rand.Uint64()))
return uint32(rand.Intn(max-min) + min)
}

View file

@ -1,59 +0,0 @@
package payload
import (
"net"
"strconv"
"time"
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//NetAddr is an abstraction for the IP layer
type NetAddr struct {
Timestamp uint32
IP [16]byte
Port uint16
Service protocol.ServiceFlag
}
//NewNetAddr returns a NetAddr object
func NewNetAddr(time uint32, ip [16]byte, port uint16, service protocol.ServiceFlag) (*NetAddr, error) {
return &NetAddr{time, ip, port, service}, nil
}
//NewAddrFromVersionMessage returns a NetAddr object from a version message
func NewAddrFromVersionMessage(version VersionMessage) (*NetAddr, error) {
var ip [16]byte
copy(ip[:], []byte(version.IP)[:16])
return NewNetAddr(version.Timestamp, ip, version.Port, version.Services)
}
// EncodePayload Implements messager interface
func (n *NetAddr) EncodePayload(bw *util.BinWriter) {
bw.Write(uint32(time.Now().Unix()))
bw.Write(protocol.NodePeerService)
bw.WriteBigEnd(n.IP)
bw.WriteBigEnd(n.Port)
}
// DecodePayload Implements Messager interface
func (n *NetAddr) DecodePayload(br *util.BinReader) {
br.Read(&n.Timestamp)
br.Read(&n.Service)
br.ReadBigEnd(&n.IP)
br.ReadBigEnd(&n.Port)
}
//IPPort returns the IPPort from the NetAddr
func (n *NetAddr) IPPort() string {
ip := net.IP(n.IP[:]).String()
port := strconv.Itoa(int(n.Port))
ipport := ip + ":" + port
return ipport
}

View file

@ -152,5 +152,20 @@ func (b *Block) DecodeBinary(r io.Reader) error {
// EncodeBinary encodes the block to the given writer. // EncodeBinary encodes the block to the given writer.
func (b *Block) EncodeBinary(w io.Writer) error { func (b *Block) EncodeBinary(w io.Writer) error {
err := b.BlockBase.EncodeBinary(w)
if err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(b.Transactions)))
if bw.Err != nil {
return err
}
for _, tx := range b.Transactions {
err := tx.EncodeBinary(w)
if err != nil {
return err
}
}
return nil return nil
} }

File diff suppressed because one or more lines are too long

View file

@ -42,7 +42,7 @@ func (attr *Attribute) DecodeBinary(r io.Reader) error {
Remark12, Remark13, Remark14, Remark15: Remark12, Remark13, Remark14, Remark15:
datasize = br.ReadVarUint() datasize = br.ReadVarUint()
default: default:
return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", attr.Usage) return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Usage))
} }
attr.Data = make([]byte, datasize) attr.Data = make([]byte, datasize)
br.ReadLE(attr.Data) br.ReadLE(attr.Data)
@ -73,17 +73,19 @@ func (attr *Attribute) EncodeBinary(w io.Writer) error {
// Size returns the size in number bytes of the Attribute // Size returns the size in number bytes of the Attribute
func (attr *Attribute) Size() int { func (attr *Attribute) Size() int {
sz := 1 // usage
switch attr.Usage { switch attr.Usage {
case ContractHash, ECDH02, ECDH03, Vote, case ContractHash, ECDH02, ECDH03, Vote,
Hash1, Hash2, Hash3, Hash4, Hash5, Hash6, Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15: Hash1, Hash2, Hash3, Hash4, Hash5, Hash6, Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15:
return 33 // uint8 + 32 = size(attrUsage) + 32 sz += 32 // uint8 + 32 = size(attrUsage) + 32
case Script: case Script:
return 21 // uint8 + 20 = size(attrUsage) + 20 sz += 20 // uint8 + 20 = size(attrUsage) + 20
case Description: case DescriptionURL:
return 2 + len(attr.Data) // uint8 + uint8+ len of data = size(attrUsage) + size(byte) + len of data sz += 1
default: default:
return 1 + len(attr.Data) // uint8 + len of data = size(attrUsage) + len of data sz += util.GetVarSize(attr.Data)
} }
return sz
} }
// MarshalJSON implements the json Marschaller interface // MarshalJSON implements the json Marschaller interface

View file

@ -42,3 +42,11 @@ func (tx *ClaimTX) EncodeBinary(w io.Writer) error {
} }
return nil return nil
} }
func (tx *ClaimTX) Size() int {
sz := util.GetVarSize(uint64(len(tx.Claims)))
for _, claim := range tx.Claims {
sz += claim.Size()
}
return sz
}

View file

@ -23,3 +23,7 @@ func (tx *ContractTX) DecodeBinary(r io.Reader) error {
func (tx *ContractTX) EncodeBinary(w io.Writer) error { func (tx *ContractTX) EncodeBinary(w io.Writer) error {
return nil return nil
} }
func (tx *ContractTX) Size() int {
return 0
}

View file

@ -26,3 +26,7 @@ func (tx *EnrollmentTX) DecodeBinary(r io.Reader) error {
func (tx *EnrollmentTX) EncodeBinary(w io.Writer) error { func (tx *EnrollmentTX) EncodeBinary(w io.Writer) error {
return tx.PublicKey.EncodeBinary(w) return tx.PublicKey.EncodeBinary(w)
} }
func (tx *EnrollmentTX) Size() int {
return len(tx.PublicKey.Bytes())
}

View file

@ -14,6 +14,7 @@ type InvocationTX struct {
// Gas cost of the smart contract. // Gas cost of the smart contract.
Gas util.Fixed8 Gas util.Fixed8
Version uint8
} }
// NewInvocationTX returns a new invocation transaction. // NewInvocationTX returns a new invocation transaction.
@ -35,7 +36,11 @@ func NewInvocationTX(script []byte) *Transaction {
func (tx *InvocationTX) DecodeBinary(r io.Reader) error { func (tx *InvocationTX) DecodeBinary(r io.Reader) error {
br := util.BinReader{R: r} br := util.BinReader{R: r}
tx.Script = br.ReadBytes() tx.Script = br.ReadBytes()
if (tx.Version >= 1) {
br.ReadLE(&tx.Gas) br.ReadLE(&tx.Gas)
} else {
tx.Gas = util.Fixed8FromInt64(0)
}
return br.Err return br.Err
} }
@ -43,6 +48,16 @@ func (tx *InvocationTX) DecodeBinary(r io.Reader) error {
func (tx *InvocationTX) EncodeBinary(w io.Writer) error { func (tx *InvocationTX) EncodeBinary(w io.Writer) error {
bw := util.BinWriter{W: w} bw := util.BinWriter{W: w}
bw.WriteBytes(tx.Script) bw.WriteBytes(tx.Script)
if (tx.Version >= 1) {
bw.WriteLE(tx.Gas) bw.WriteLE(tx.Gas)
}
return bw.Err return bw.Err
} }
func (tx *InvocationTX) Size() int {
sz := util.GetVarSize(tx.Script)
if (tx.Version >= 1) {
sz += tx.Gas.Size()
}
return sz
}

View file

@ -17,3 +17,7 @@ func (tx *IssueTX) DecodeBinary(r io.Reader) error {
func (tx *IssueTX) EncodeBinary(w io.Writer) error { func (tx *IssueTX) EncodeBinary(w io.Writer) error {
return nil return nil
} }
func (tx *IssueTX) Size() int {
return 0
}

View file

@ -20,3 +20,7 @@ func (tx *MinerTX) DecodeBinary(r io.Reader) error {
func (tx *MinerTX) EncodeBinary(w io.Writer) error { func (tx *MinerTX) EncodeBinary(w io.Writer) error {
return binary.Write(w, binary.LittleEndian, tx.Nonce) return binary.Write(w, binary.LittleEndian, tx.Nonce)
} }
func (tx *MinerTX) Size() int {
return 4 // Nonce
}

View file

@ -58,3 +58,16 @@ func (tx *PublishTX) DecodeBinary(r io.Reader) error {
func (tx *PublishTX) EncodeBinary(w io.Writer) error { func (tx *PublishTX) EncodeBinary(w io.Writer) error {
return nil return nil
} }
func (tx *PublishTX) Size() int {
sz := util.GetVarSize(tx.Script) + util.GetVarSize(uint64(len(tx.ParamList)))
sz += 1 * len(tx.ParamList)
sz += 1
if tx.Version >= 1 {
sz += 1
}
sz += util.GetVarSize(tx.Name) + util.GetVarSize(tx.CodeVersion)
sz += util.GetVarSize(tx.Author) + util.GetVarSize(tx.Email)
sz += util.GetVarSize(tx.Description)
return sz
}

View file

@ -62,3 +62,7 @@ func (tx *RegisterTX) EncodeBinary(w io.Writer) error {
bw.WriteLE(tx.Admin) bw.WriteLE(tx.Admin)
return bw.Err return bw.Err
} }
func (tx *RegisterTX) Size() int {
return 1 + util.GetVarSize(tx.Name) + tx.Amount.Size() + 1 + len(tx.Owner.Bytes()) + tx.Admin.Size()
}

View file

@ -31,3 +31,11 @@ func (tx *StateTX) DecodeBinary(r io.Reader) error {
func (tx *StateTX) EncodeBinary(w io.Writer) error { func (tx *StateTX) EncodeBinary(w io.Writer) error {
return nil return nil
} }
func (tx *StateTX) Size() int {
sz := util.GetVarSize(uint64(len(tx.Descriptors)))
for _, desc := range tx.Descriptors {
sz += desc.Size()
}
return sz
}

View file

@ -39,3 +39,7 @@ func (s *StateDescriptor) DecodeBinary(r io.Reader) error {
func (s *StateDescriptor) EncodeBinary(w io.Writer) error { func (s *StateDescriptor) EncodeBinary(w io.Writer) error {
return nil return nil
} }
func (s *StateDescriptor) Size() int {
return 1 + util.GetVarSize(s.Key) + util.GetVarSize(s.Value) + util.GetVarSize(s.Field)
}

View file

@ -136,7 +136,7 @@ func (t *Transaction) DecodeBinary(r io.Reader) error {
func (t *Transaction) decodeData(r io.Reader) error { func (t *Transaction) decodeData(r io.Reader) error {
switch t.Type { switch t.Type {
case InvocationType: case InvocationType:
t.Data = &InvocationTX{} t.Data = &InvocationTX{Version: t.Version}
return t.Data.(*InvocationTX).DecodeBinary(r) return t.Data.(*InvocationTX).DecodeBinary(r)
case MinerType: case MinerType:
t.Data = &MinerTX{} t.Data = &MinerTX{}
@ -276,8 +276,7 @@ func (t *Transaction) Size() int {
outputSize := util.GetVarSize(t.Outputs) outputSize := util.GetVarSize(t.Outputs)
witnesSize := util.GetVarSize(t.Scripts) witnesSize := util.GetVarSize(t.Scripts)
// uint8 + uint8 + attrSize + inputSize + outputSize + witnesSize // uint8 + uint8 + attrSize + inputSize + outputSize + witnesSize
return 2 + attrSize + inputSize + outputSize + witnesSize return 2 + attrSize + inputSize + outputSize + witnesSize + t.Data.Size()
} }
// Bytes convert the transaction to []byte // Bytes convert the transaction to []byte

View file

@ -7,4 +7,5 @@ import "io"
type TXer interface { type TXer interface {
DecodeBinary(io.Reader) error DecodeBinary(io.Reader) error
EncodeBinary(io.Writer) error EncodeBinary(io.Writer) error
Size() int
} }

View file

@ -186,7 +186,7 @@ func (m *Message) decodePayload(r io.Reader) error {
if err := p.DecodeBinary(buf); err != nil { if err := p.DecodeBinary(buf); err != nil {
return err return err
} }
case CMDInv: case CMDInv, CMDGetData:
p = &payload.Inventory{} p = &payload.Inventory{}
if err := p.DecodeBinary(buf); err != nil { if err := p.DecodeBinary(buf); err != nil {
return err return err
@ -201,6 +201,8 @@ func (m *Message) decodePayload(r io.Reader) error {
if err := p.DecodeBinary(buf); err != nil { if err := p.DecodeBinary(buf); err != nil {
return err return err
} }
case CMDGetBlocks:
fallthrough
case CMDGetHeaders: case CMDGetHeaders:
p = &payload.GetBlocks{} p = &payload.GetBlocks{}
if err := p.DecodeBinary(buf); err != nil { if err := p.DecodeBinary(buf); err != nil {

View file

@ -13,18 +13,19 @@ import (
func TestEncodeDecodeAddress(t *testing.T) { func TestEncodeDecodeAddress(t *testing.T) {
var ( var (
e = util.NewEndpoint("127.0.0.1:2000") e = util.NewEndpoint("127.0.0.1:2000")
addr = NewAddressAndTime(e, time.Now()) ts = time.Now()
addr = NewAddressAndTime(e, ts)
buf = new(bytes.Buffer) buf = new(bytes.Buffer)
) )
if err := addr.EncodeBinary(buf); err != nil { assert.Equal(t, ts.UTC().Unix(), int64(addr.Timestamp))
t.Fatal(err) assert.Equal(t, e, addr.Endpoint)
} err := addr.EncodeBinary(buf)
assert.Nil(t, err)
addrDecode := &AddressAndTime{} addrDecode := &AddressAndTime{}
if err := addrDecode.DecodeBinary(buf); err != nil { err = addrDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
assert.Equal(t, addr, addrDecode) assert.Equal(t, addr, addrDecode)
} }
@ -38,14 +39,12 @@ func TestEncodeDecodeAddressList(t *testing.T) {
} }
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := addrList.EncodeBinary(buf); err != nil { err := addrList.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
addrListDecode := &AddressList{} addrListDecode := &AddressList{}
if err := addrListDecode.DecodeBinary(buf); err != nil { err = addrListDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
assert.Equal(t, addrList, addrListDecode) assert.Equal(t, addrList, addrListDecode)
} }

View file

@ -19,15 +19,12 @@ func TestGetBlockEncodeDecode(t *testing.T) {
p := NewGetBlocks(start, util.Uint256{}) p := NewGetBlocks(start, util.Uint256{})
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := p.EncodeBinary(buf); err != nil { err := p.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
pDecode := &GetBlocks{} pDecode := &GetBlocks{}
if err := pDecode.DecodeBinary(buf); err != nil { err = pDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
assert.Equal(t, p, pDecode) assert.Equal(t, p, pDecode)
} }
@ -43,14 +40,11 @@ func TestGetBlockEncodeDecodeWithHashStop(t *testing.T) {
) )
p := NewGetBlocks(start, stop) p := NewGetBlocks(start, stop)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := p.EncodeBinary(buf); err != nil { err := p.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
pDecode := &GetBlocks{} pDecode := &GetBlocks{}
if err := pDecode.DecodeBinary(buf); err != nil { err = pDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
assert.Equal(t, p, pDecode) assert.Equal(t, p, pDecode)
} }

View file

@ -5,6 +5,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core"
"github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/util"
log "github.com/sirupsen/logrus"
) )
// Headers payload // Headers payload
@ -12,6 +13,11 @@ type Headers struct {
Hdrs []*core.Header Hdrs []*core.Header
} }
// Users can at most request 2k header
const (
maxHeadersAllowed = 2000
)
// DecodeBinary implements the Payload interface. // DecodeBinary implements the Payload interface.
func (p *Headers) DecodeBinary(r io.Reader) error { func (p *Headers) DecodeBinary(r io.Reader) error {
br := util.BinReader{R: r} br := util.BinReader{R: r}
@ -19,6 +25,11 @@ func (p *Headers) DecodeBinary(r io.Reader) error {
if br.Err != nil { if br.Err != nil {
return br.Err return br.Err
} }
// C# node does it silently
if lenHeaders > maxHeadersAllowed {
log.Warnf("received %d headers, capping to %d", lenHeaders, maxHeadersAllowed)
lenHeaders = maxHeadersAllowed
}
p.Hdrs = make([]*core.Header, lenHeaders) p.Hdrs = make([]*core.Header, lenHeaders)

View file

@ -2,6 +2,7 @@ package payload
import ( import (
"bytes" "bytes"
"encoding/hex"
"testing" "testing"
"github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core"
@ -41,14 +42,12 @@ func TestHeadersEncodeDecode(t *testing.T) {
}} }}
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := headers.EncodeBinary(buf); err != nil { err := headers.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
headersDecode := &Headers{} headersDecode := &Headers{}
if err := headersDecode.DecodeBinary(buf); err != nil { err = headersDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
for i := 0; i < len(headers.Hdrs); i++ { for i := 0; i < len(headers.Hdrs); i++ {
assert.Equal(t, headers.Hdrs[i].Version, headersDecode.Hdrs[i].Version) assert.Equal(t, headers.Hdrs[i].Version, headersDecode.Hdrs[i].Version)
@ -56,3 +55,28 @@ func TestHeadersEncodeDecode(t *testing.T) {
assert.Equal(t, headers.Hdrs[i].Script, headersDecode.Hdrs[i].Script) assert.Equal(t, headers.Hdrs[i].Script, headersDecode.Hdrs[i].Script)
} }
} }
func TestBinEncodeDecode(t *testing.T) {
rawBlockHeaders := "010000000026b3c3df4dc1602a3b0e6989248b23275b5e4014a159af5dce69e16d4ab75f00f439321a51f425a530820cfe4d715bfd835b49687e87772f2c4737b8bc586dca7fda03580a000000bf14ff160228f0c059e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd45014036fdd23248880c1c311bcd97df04fe6d740dc1bf340c26915f0466e31e81c039012eca7a760270389e04b58b99820fe49cf8c24c9afc65d696b4d3f406a1e6b5405172a9b461e68dd399c8716de11d31f7dd2ec3be327c636b024562db6ac5df1cffdbee74c994736fd49803234d2baffbc0054f28ba5ec76494a467b4106955bb4084af7746d269241628c667003e9d39288b190ad5cef218ada625cbba8be411bb153828d8d3634e8f586638e2448425bc5b671be69800392ccbdebc945a5099c7406f6a11824105ecad345e525957053e77fbc0119d6b3fa7f854527e816cfce0d95dac66888e07e8990c95103d8e46124aac16f152e088520d7ec8325e3a2456f840e5b77ef0e3c410b347ccaf8a87516d10b88d436563c80712153273993afc320ec49b638225f58de464a1345e62a564b398939f96f6f4b7cf21b583609f85495af1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae00"
var headerMsg Headers
rawBlockBytes, _ := hex.DecodeString(rawBlockHeaders)
r := bytes.NewReader(rawBlockBytes)
err := headerMsg.DecodeBinary(r)
assert.Nil(t, err)
assert.Equal(t, 1, len(headerMsg.Hdrs))
header := headerMsg.Hdrs[0]
hash := header.Hash()
assert.Equal(t, "f3c4ec44c07eccbda974f1ee34bc6654ab6d3f22cd89c2e5c593a16d6cc7e6e8", hash.ReverseString())
buf := new(bytes.Buffer)
err = headerMsg.EncodeBinary(buf)
assert.Equal(t, nil, err)
assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(buf.Bytes()))
}

View file

@ -16,9 +16,9 @@ type InventoryType uint8
func (i InventoryType) String() string { func (i InventoryType) String() string {
switch i { switch i {
case 0x01: case 0x01:
return "block"
case 0x02:
return "TX" return "TX"
case 0x02:
return "block"
case 0xe0: case 0xe0:
return "consensus" return "consensus"
default: default:

View file

@ -2,11 +2,11 @@ package payload
import ( import (
"bytes" "bytes"
"reflect"
"testing" "testing"
"github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/hash"
. "github.com/CityOfZion/neo-go/pkg/util" . "github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/assert"
) )
func TestInventoryEncodeDecode(t *testing.T) { func TestInventoryEncodeDecode(t *testing.T) {
@ -17,16 +17,21 @@ func TestInventoryEncodeDecode(t *testing.T) {
inv := NewInventory(BlockType, hashes) inv := NewInventory(BlockType, hashes)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := inv.EncodeBinary(buf); err != nil { err := inv.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
}
invDecode := &Inventory{} invDecode := &Inventory{}
if err := invDecode.DecodeBinary(buf); err != nil { err = invDecode.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
} assert.Equal(t, inv, invDecode)
}
if !reflect.DeepEqual(inv, invDecode) {
t.Fatalf("expected both inventories to be equal %v and %v", inv, invDecode) func TestEmptyInv(t *testing.T) {
} msgInv := NewInventory(TXType, []Uint256{})
buf := new(bytes.Buffer)
err := msgInv.EncodeBinary(buf)
assert.Nil(t, err)
assert.Equal(t, []byte{byte(TXType), 0}, buf.Bytes())
assert.Equal(t, 0, len(msgInv.Hashes))
} }

View file

@ -7,6 +7,8 @@ import (
"github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/util"
) )
// Size of the payload not counting UserAgent encoding (which is at least 1 byte
// for zero-length string)
const minVersionSize = 27 const minVersionSize = 27
// List of Services offered by the node // List of Services offered by the node
@ -83,5 +85,5 @@ func (p *Version) EncodeBinary(w io.Writer) error {
// Size implements the payloader interface. // Size implements the payloader interface.
func (p *Version) Size() uint32 { func (p *Version) Size() uint32 {
return uint32(minVersionSize + len(p.UserAgent)) return uint32(minVersionSize + util.GetVarSize(p.UserAgent))
} }

View file

@ -2,28 +2,32 @@ package payload
import ( import (
"bytes" "bytes"
"reflect"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func TestVersionEncodeDecode(t *testing.T) { func TestVersionEncodeDecode(t *testing.T) {
version := NewVersion(13337, 3000, "/NEO:0.0.1/", 0, true) var port uint16 = 3000
var id uint32 = 13337
useragent := "/NEO:0.0.1/"
var height uint32 = 100500
var relay bool = true
version := NewVersion(id, port, useragent, height, relay)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := version.EncodeBinary(buf); err != nil { err := version.EncodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
} assert.Equal(t, int(version.Size()), buf.Len())
versionDecoded := &Version{} versionDecoded := &Version{}
if err := versionDecoded.DecodeBinary(buf); err != nil { err = versionDecoded.DecodeBinary(buf)
t.Fatal(err) assert.Nil(t, err)
} assert.Equal(t, versionDecoded.Nonce, id)
assert.Equal(t, versionDecoded.Port, port)
if !reflect.DeepEqual(version, versionDecoded) { assert.Equal(t, versionDecoded.UserAgent, []byte(useragent))
t.Fatalf("expected both version payload to be equal: %+v and %+v", version, versionDecoded) assert.Equal(t, versionDecoded.StartHeight, height)
} assert.Equal(t, versionDecoded.Relay, relay)
assert.Equal(t, version, versionDecoded)
if version.Size() != uint32(minVersionSize+len(version.UserAgent)) {
t.Fatalf("Expected version size of %d", minVersionSize+len(version.UserAgent))
}
} }

View file

@ -224,12 +224,11 @@ var testRpcCases = []tc{
expectedResult: `{"jsonrpc":"2.0","result":true,"id":1}`, expectedResult: `{"jsonrpc":"2.0","result":true,"id":1}`,
}, },
/* Good case: TODO: uncomment this test case once https://github.com/CityOfZion/neo-go/issues/173 is fixed!
{ {
rpcCall: `{ "jsonrpc": "2.0", "id": 1, "method": "sendrawtransaction", "params": ["d1001b00046e616d6567d3d8602814a429a91afdbaa3914884a1c90c733101201cc9c05cefffe6cdd7b182816a9152ec218d2ec000000141403387ef7940a5764259621e655b3c621a6aafd869a611ad64adcc364d8dd1edf84e00a7f8b11b630a377eaef02791d1c289d711c08b7ad04ff0d6c9caca22cfe6232103cbb45da6072c14761c9da545749d9cfd863f860c351066d16df480602a2024c6ac"] }`, rpcCall: `{ "jsonrpc": "2.0", "id": 1, "method": "sendrawtransaction", "params": ["d1001b00046e616d6567d3d8602814a429a91afdbaa3914884a1c90c733101201cc9c05cefffe6cdd7b182816a9152ec218d2ec000000141403387ef7940a5764259621e655b3c621a6aafd869a611ad64adcc364d8dd1edf84e00a7f8b11b630a377eaef02791d1c289d711c08b7ad04ff0d6c9caca22cfe6232103cbb45da6072c14761c9da545749d9cfd863f860c351066d16df480602a2024c6ac"] }`,
method: "sendrawtransaction_2", method: "sendrawtransaction_2",
expectedResult: `{"jsonrpc":"2.0","result":true,"id":1}`, expectedResult: `{"jsonrpc":"2.0","result":true,"id":1}`,
},*/ },
// Bad case, incorrect raw transaction // Bad case, incorrect raw transaction
{ {