forked from TrueCloudLab/neoneo-go
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:
commit
d0c39a561c
50 changed files with 360 additions and 1492 deletions
|
@ -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
|
@ -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
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package payload
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
|
||||||
//tests for this have been included in the mheaders_test 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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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()))
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
|
|
@ -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())
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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()))
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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())
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
br.ReadLE(&tx.Gas)
|
if (tx.Version >= 1) {
|
||||||
|
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)
|
||||||
bw.WriteLE(tx.Gas)
|
if (tx.Version >= 1) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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()))
|
||||||
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue