Merge pull request #322 from nspcc-dev/drop-redundant-dev-code-part-3

Drop redundant dev code part 3, refs. #307, #315 and #318.
This commit is contained in:
Roman Khimov 2019-08-29 15:04:05 +03:00 committed by GitHub
commit c6d7ef2de4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 515 additions and 922 deletions

View file

@ -1,29 +0,0 @@
package command
// Size of command field in bytes
const (
Size = 12
)
// Type represents the type of a message command.
type Type string
// Valid protocol commands used to send between nodes.
const (
Version Type = "version"
Mempool Type = "mempool"
Ping Type = "ping"
Pong Type = "pong"
Verack Type = "verack"
GetAddr Type = "getaddr"
Addr Type = "addr"
GetHeaders Type = "getheaders"
Headers Type = "headers"
GetBlocks Type = "getblocks"
Inv Type = "inv"
GetData Type = "getdata"
Block Type = "block"
TX Type = "tx"
Consensus Type = "consensus"
Unknown Type = "unknown"
)

View file

@ -47,7 +47,7 @@ func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
return err
}
payloadLen := util.BufferLength(buf)
payloadLen := uint32(buf.Len())
checksum := checksum.FromBytes(buf.Bytes())
bw.Write(payloadLen)

View file

@ -1,44 +0,0 @@
package protocol
//Version represents the latest protocol version for the neo node
type Version uint32
const (
// DefaultVersion is the nodes default protocol version
DefaultVersion Version = 0
// UserAgent is the nodes user agent or human-readable name
UserAgent = "/NEO-GO/"
)
// ServiceFlag indicates the services provided by the node. 1 = P2P Full Node
type ServiceFlag uint64
// List of Services offered by the node
const (
NodePeerService ServiceFlag = 1
// BloomFilerService ServiceFlag = 2 // Not implemented
// PrunedNode ServiceFlag = 3 // Not implemented
// LightNode ServiceFlag = 4 // Not implemented
)
// Magic is the network that NEO is running on
type Magic uint32
// List of possible networks
const (
MainNet Magic = 7630401
TestNet Magic = 0x74746e41
)
// String implements the stringer interface
func (m Magic) String() string {
switch m {
case MainNet:
return "Mainnet"
case TestNet:
return "Testnet"
default:
return "UnknownNet"
}
}

View file

@ -1,49 +0,0 @@
package util
import (
"bytes"
"crypto/sha256"
"io"
"io/ioutil"
)
// Convenience function
// BufferLength returns the length of a buffer as uint32
func BufferLength(buf *bytes.Buffer) uint32 {
return uint32(buf.Len())
}
// SumSHA256 returns the sha256 sum of the data
func SumSHA256(b []byte) []byte {
h := sha256.New()
h.Write(b)
return h.Sum(nil)
}
// CalculateHash takes a function with a binary writer and returns
// the double hash of the io.Writer
func CalculateHash(f func(bw *BinWriter)) (Uint256, error) {
buf := new(bytes.Buffer)
bw := &BinWriter{W: buf}
f(bw)
var hash Uint256
hash = sha256.Sum256(buf.Bytes())
hash = sha256.Sum256(hash.Bytes())
return hash, bw.Err
}
//ReaderToBuffer converts a io.Reader into a bytes.Buffer
func ReaderToBuffer(r io.Reader) (*bytes.Buffer, error) {
byt, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(byt)
return buf, nil
}

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"fmt"
"io"
@ -69,17 +68,11 @@ func NewAccountState(scriptHash util.Uint160) *AccountState {
// DecodeBinary decodes AccountState from the given io.Reader.
func (s *AccountState) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &s.Version); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &s.ScriptHash); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &s.IsFrozen); err != nil {
return err
}
lenVotes := util.ReadVarUint(r)
br := util.BinReader{R: r}
br.ReadLE(&s.Version)
br.ReadLE(&s.ScriptHash)
br.ReadLE(&s.IsFrozen)
lenVotes := br.ReadVarUint()
s.Votes = make([]*keys.PublicKey, lenVotes)
for i := 0; i < int(lenVotes); i++ {
s.Votes[i] = &keys.PublicKey{}
@ -89,37 +82,25 @@ func (s *AccountState) DecodeBinary(r io.Reader) error {
}
s.Balances = make(map[util.Uint256]util.Fixed8)
lenBalances := util.ReadVarUint(r)
lenBalances := br.ReadVarUint()
for i := 0; i < int(lenBalances); i++ {
key := util.Uint256{}
if err := binary.Read(r, binary.LittleEndian, &key); err != nil {
return err
}
br.ReadLE(&key)
var val util.Fixed8
if err := binary.Read(r, binary.LittleEndian, &val); err != nil {
return err
}
br.ReadLE(&val)
s.Balances[key] = val
}
return nil
return br.Err
}
// EncodeBinary encode AccountState to the given io.Writer.
func (s *AccountState) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, s.Version); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, s.ScriptHash); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, s.IsFrozen); err != nil {
return err
}
if err := util.WriteVarUint(w, uint64(len(s.Votes))); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteLE(s.Version)
bw.WriteLE(s.ScriptHash)
bw.WriteLE(s.IsFrozen)
bw.WriteVarUint(uint64(len(s.Votes)))
for _, point := range s.Votes {
if err := point.EncodeBinary(w); err != nil {
return err
@ -127,19 +108,13 @@ func (s *AccountState) EncodeBinary(w io.Writer) error {
}
balances := s.nonZeroBalances()
if err := util.WriteVarUint(w, uint64(len(balances))); err != nil {
return err
}
bw.WriteVarUint(uint64(len(balances)))
for k, v := range balances {
if err := binary.Write(w, binary.LittleEndian, k); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, v); err != nil {
return err
}
bw.WriteLE(k)
bw.WriteLE(v)
}
return nil
return bw.Err
}
// Returns only the non-zero balances for the account.

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/core/storage"
@ -48,95 +47,56 @@ type AssetState struct {
// DecodeBinary implements the Payload interface.
func (a *AssetState) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &a.ID); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.AssetType); err != nil {
return err
}
br := util.BinReader{R: r}
br.ReadLE(&a.ID)
br.ReadLE(&a.AssetType)
var err error
a.Name, err = util.ReadVarString(r)
if err != nil {
return err
}
a.Name = br.ReadString()
if err := binary.Read(r, binary.LittleEndian, &a.Amount); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.Available); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.Precision); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.FeeMode); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.FeeAddress); err != nil {
return err
}
br.ReadLE(&a.Amount)
br.ReadLE(&a.Available)
br.ReadLE(&a.Precision)
br.ReadLE(&a.FeeMode)
br.ReadLE(&a.FeeAddress)
if br.Err != nil {
return br.Err
}
a.Owner = &keys.PublicKey{}
if err := a.Owner.DecodeBinary(r); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.Admin); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.Issuer); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.Expiration); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &a.IsFrozen)
br.ReadLE(&a.Admin)
br.ReadLE(&a.Issuer)
br.ReadLE(&a.Expiration)
br.ReadLE(&a.IsFrozen)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (a *AssetState) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, a.ID); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.AssetType); err != nil {
return err
}
if err := util.WriteVarUint(w, uint64(len(a.Name))); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, []byte(a.Name)); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Amount); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Available); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Precision); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.FeeMode); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteLE(a.ID)
bw.WriteLE(a.AssetType)
bw.WriteString(a.Name)
bw.WriteLE(a.Amount)
bw.WriteLE(a.Available)
bw.WriteLE(a.Precision)
bw.WriteLE(a.FeeMode)
bw.WriteLE(a.FeeAddress)
if err := binary.Write(w, binary.LittleEndian, a.FeeAddress); err != nil {
return err
if bw.Err != nil {
return bw.Err
}
if err := a.Owner.EncodeBinary(w); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Admin); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Issuer); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.Expiration); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, a.IsFrozen)
bw.WriteLE(a.Admin)
bw.WriteLE(a.Issuer)
bw.WriteLE(a.Expiration)
bw.WriteLE(a.IsFrozen)
return bw.Err
}
// GetName returns the asset name based on its type.

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
@ -79,9 +78,11 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
return block, err
}
br := util.BinReader{R: r}
var padding uint8
if err := binary.Read(r, binary.LittleEndian, &padding); err != nil {
return block, err
br.ReadLE(&padding)
if br.Err != nil {
return block, br.Err
}
block.Script = &transaction.Witness{}
@ -89,17 +90,15 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
return block, err
}
lenTX := util.ReadVarUint(r)
lenTX := br.ReadVarUint()
block.Transactions = make([]*transaction.Transaction, lenTX)
for i := 0; i < int(lenTX); i++ {
var hash util.Uint256
if err := binary.Read(r, binary.LittleEndian, &hash); err != nil {
return block, err
}
br.ReadLE(&hash)
block.Transactions[i] = transaction.NewTrimmedTX(hash)
}
return block, nil
return block, br.Err
}
// Trim returns a subset of the block data to save up space
@ -110,23 +109,22 @@ func (b *Block) Trim() ([]byte, error) {
if err := b.encodeHashableFields(buf); err != nil {
return nil, err
}
if err := binary.Write(buf, binary.LittleEndian, uint8(1)); err != nil {
return nil, err
bw := util.BinWriter{W: buf}
bw.WriteLE(uint8(1))
if bw.Err != nil {
return nil, bw.Err
}
if err := b.Script.EncodeBinary(buf); err != nil {
return nil, err
}
lenTX := uint64(len(b.Transactions))
if err := util.WriteVarUint(buf, lenTX); err != nil {
return nil, err
}
bw.WriteVarUint(uint64(len(b.Transactions)))
for _, tx := range b.Transactions {
if err := binary.Write(buf, binary.LittleEndian, tx.Hash()); err != nil {
return nil, err
}
bw.WriteLE(tx.Hash())
}
if bw.Err != nil {
return nil, bw.Err
}
return buf.Bytes(), nil
}
@ -136,7 +134,11 @@ func (b *Block) DecodeBinary(r io.Reader) error {
return err
}
lentx := util.ReadVarUint(r)
br := util.BinReader{R: r}
lentx := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
b.Transactions = make([]*transaction.Transaction, lentx)
for i := 0; i < int(lentx); i++ {
b.Transactions[i] = &transaction.Transaction{}

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"fmt"
"io"
@ -67,8 +66,10 @@ func (b *BlockBase) DecodeBinary(r io.Reader) error {
}
var padding uint8
if err := binary.Read(r, binary.LittleEndian, &padding); err != nil {
return err
br := util.BinReader{R: r}
br.ReadLE(&padding)
if br.Err != nil {
return br.Err
}
if padding != 1 {
return fmt.Errorf("format error: padding must equal 1 got %d", padding)
@ -83,8 +84,10 @@ func (b *BlockBase) EncodeBinary(w io.Writer) error {
if err := b.encodeHashableFields(w); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, uint8(1)); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteLE(uint8(1))
if bw.Err != nil {
return bw.Err
}
return b.Script.EncodeBinary(w)
}
@ -108,50 +111,31 @@ func (b *BlockBase) createHash() error {
// encodeHashableFields will only encode the fields used for hashing.
// see Hash() for more information about the fields.
func (b *BlockBase) encodeHashableFields(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, b.Version); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, b.PrevHash); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, b.MerkleRoot); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, b.Timestamp); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, b.Index); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, b.ConsensusData); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, b.NextConsensus)
bw := util.BinWriter{W: w}
bw.WriteLE(b.Version)
bw.WriteLE(b.PrevHash)
bw.WriteLE(b.MerkleRoot)
bw.WriteLE(b.Timestamp)
bw.WriteLE(b.Index)
bw.WriteLE(b.ConsensusData)
bw.WriteLE(b.NextConsensus)
return bw.Err
}
// decodeHashableFields will only decode the fields used for hashing.
// see Hash() for more information about the fields.
func (b *BlockBase) decodeHashableFields(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &b.Version); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.PrevHash); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.MerkleRoot); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.Timestamp); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.Index); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.ConsensusData); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &b.NextConsensus); err != nil {
return err
br := util.BinReader{R: r}
br.ReadLE(&b.Version)
br.ReadLE(&b.PrevHash)
br.ReadLE(&b.MerkleRoot)
br.ReadLE(&b.Timestamp)
br.ReadLE(&b.Index)
br.ReadLE(&b.ConsensusData)
br.ReadLE(&b.NextConsensus)
if br.Err != nil {
return br.Err
}
// Make the hash of the block here so we dont need to do this

View file

@ -1,7 +1,6 @@
package core
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -60,14 +59,11 @@ func (l *HeaderHashList) Slice(start, end int) []util.Uint256 {
// WriteTo will write n underlying hashes to the given io.Writer
// starting from start.
func (l *HeaderHashList) Write(w io.Writer, start, n int) error {
if err := util.WriteVarUint(w, uint64(n)); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(n))
hashes := l.Slice(start, start+n)
for _, hash := range hashes {
if err := binary.Write(w, binary.LittleEndian, hash); err != nil {
return err
}
bw.WriteLE(hash)
}
return nil
return bw.Err
}

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"fmt"
"io"
@ -68,49 +67,33 @@ func NewSpentCoinState(hash util.Uint256, height uint32) *SpentCoinState {
// DecodeBinary implements the Payload interface.
func (s *SpentCoinState) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &s.txHash); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &s.txHeight); err != nil {
return err
}
br := util.BinReader{R: r}
br.ReadLE(&s.txHash)
br.ReadLE(&s.txHeight)
s.items = make(map[uint16]uint32)
lenItems := util.ReadVarUint(r)
lenItems := br.ReadVarUint()
for i := 0; i < int(lenItems); i++ {
var (
key uint16
value uint32
)
if err := binary.Read(r, binary.LittleEndian, &key); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &value); err != nil {
return err
}
br.ReadLE(&key)
br.ReadLE(&value)
s.items[key] = value
}
return nil
return br.Err
}
// EncodeBinary implements the Payload interface.
func (s *SpentCoinState) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, s.txHash); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, s.txHeight); err != nil {
return err
}
if err := util.WriteVarUint(w, uint64(len(s.items))); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteLE(s.txHash)
bw.WriteLE(s.txHeight)
bw.WriteVarUint(uint64(len(s.items)))
for k, v := range s.items {
if err := binary.Write(w, binary.LittleEndian, k); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, v); err != nil {
return err
}
bw.WriteLE(k)
bw.WriteLE(v)
}
return nil
return bw.Err
}

View file

@ -1,6 +1,7 @@
package storage
import (
"bytes"
"encoding/binary"
"sort"
@ -55,7 +56,7 @@ func HeaderHashes(s Store) ([]util.Uint256, error) {
hashMap := make(map[uint32][]util.Uint256)
s.Seek(IXHeaderHashList.Bytes(), func(k, v []byte) {
storedCount := binary.LittleEndian.Uint32(k[1:])
hashes, err := util.Read2000Uint256Hashes(v)
hashes, err := read2000Uint256Hashes(v)
if err != nil {
panic(err)
}
@ -78,3 +79,17 @@ func HeaderHashes(s Store) ([]util.Uint256, error) {
return hashes, nil
}
// read2000Uint256Hashes attempts to read 2000 Uint256 hashes from
// the given byte array.
func read2000Uint256Hashes(b []byte) ([]util.Uint256, error) {
r := bytes.NewReader(b)
br := util.BinReader{R: r}
lenHashes := br.ReadVarUint()
hashes := make([]util.Uint256, lenHashes)
br.ReadLE(hashes)
if br.Err != nil {
return nil, br.Err
}
return hashes, nil
}

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
@ -18,66 +17,58 @@ type Attribute struct {
// DecodeBinary implements the Payload interface.
func (attr *Attribute) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &attr.Usage); err != nil {
return err
}
if attr.Usage == ContractHash ||
attr.Usage == Vote ||
(attr.Usage >= Hash1 && attr.Usage <= Hash15) {
attr.Data = make([]byte, 32)
return binary.Read(r, binary.LittleEndian, attr.Data)
}
br := util.BinReader{R: r}
br.ReadLE(&attr.Usage)
// very special case
if attr.Usage == ECDH02 || attr.Usage == ECDH03 {
attr.Data = make([]byte, 33)
attr.Data[0] = byte(attr.Usage)
return binary.Read(r, binary.LittleEndian, attr.Data[1:])
br.ReadLE(attr.Data[1:])
return br.Err
}
if attr.Usage == Script {
attr.Data = make([]byte, 20)
return binary.Read(r, binary.LittleEndian, attr.Data)
var datasize uint64
switch attr.Usage {
case ContractHash, Vote, Hash1, Hash2, Hash3, Hash4, Hash5,
Hash6, Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13,
Hash14, Hash15:
datasize = 32
case Script:
datasize = 20
case DescriptionURL:
datasize = 1
case Description, Remark, Remark1, Remark2, Remark3, Remark4,
Remark5, Remark6, Remark7, Remark8, Remark9, Remark10, Remark11,
Remark12, Remark13, Remark14, Remark15:
datasize = br.ReadVarUint()
default:
return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", attr.Usage)
}
if attr.Usage == DescriptionURL {
attr.Data = make([]byte, 1)
return binary.Read(r, binary.LittleEndian, attr.Data)
}
if attr.Usage == Description || attr.Usage >= Remark {
lenData := util.ReadVarUint(r)
attr.Data = make([]byte, lenData)
return binary.Read(r, binary.LittleEndian, attr.Data)
}
return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", attr.Usage)
attr.Data = make([]byte, datasize)
br.ReadLE(attr.Data)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (attr *Attribute) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, &attr.Usage); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteLE(&attr.Usage)
switch attr.Usage {
case ECDH02, ECDH03:
bw.WriteLE(attr.Data[1:])
case DescriptionURL, Description, Remark, Remark1, Remark2, Remark3, Remark4,
Remark5, Remark6, Remark7, Remark8, Remark9, Remark10, Remark11,
Remark12, Remark13, Remark14, Remark15:
bw.WriteVarUint(uint64(len(attr.Data)))
fallthrough
case Script, ContractHash, Vote, Hash1, Hash2, Hash3, Hash4, Hash5, Hash6,
Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15:
bw.WriteLE(attr.Data)
default:
return fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage)
}
if attr.Usage == ContractHash ||
attr.Usage == Vote ||
(attr.Usage >= Hash1 && attr.Usage <= Hash15) {
return binary.Write(w, binary.LittleEndian, attr.Data)
}
if attr.Usage == ECDH02 || attr.Usage == ECDH03 {
attr.Data[0] = byte(attr.Usage)
return binary.Write(w, binary.LittleEndian, attr.Data[1:33])
}
if attr.Usage == Script {
return binary.Write(w, binary.LittleEndian, attr.Data)
}
if attr.Usage == DescriptionURL {
if err := util.WriteVarUint(w, uint64(len(attr.Data))); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, attr.Data)
}
if attr.Usage == Description || attr.Usage >= Remark {
if err := util.WriteVarUint(w, uint64(len(attr.Data))); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, attr.Data)
}
return fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage)
return bw.Err
}
// Size returns the size in number bytes of the Attribute

View file

@ -13,7 +13,11 @@ type ClaimTX struct {
// DecodeBinary implements the Payload interface.
func (tx *ClaimTX) DecodeBinary(r io.Reader) error {
lenClaims := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenClaims := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
tx.Claims = make([]*Input, lenClaims)
for i := 0; i < int(lenClaims); i++ {
tx.Claims[i] = &Input{}
@ -26,8 +30,10 @@ func (tx *ClaimTX) DecodeBinary(r io.Reader) error {
// EncodeBinary implements the Payload interface.
func (tx *ClaimTX) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(tx.Claims))); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(tx.Claims)))
if bw.Err != nil {
return bw.Err
}
for _, claim := range tx.Claims {
if err := claim.EncodeBinary(w); err != nil {

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -18,21 +17,18 @@ type Input struct {
// DecodeBinary implements the Payload interface.
func (in *Input) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &in.PrevHash); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &in.PrevIndex)
br := util.BinReader{R: r}
br.ReadLE(&in.PrevHash)
br.ReadLE(&in.PrevIndex)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (in *Input) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, in.PrevHash); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, in.PrevIndex); err != nil {
return err
}
return nil
bw := util.BinWriter{W: w}
bw.WriteLE(in.PrevHash)
bw.WriteLE(in.PrevIndex)
return bw.Err
}
// Size returns the size in bytes of the Input

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -34,21 +33,16 @@ func NewInvocationTX(script []byte) *Transaction {
// DecodeBinary implements the Payload interface.
func (tx *InvocationTX) DecodeBinary(r io.Reader) error {
lenScript := util.ReadVarUint(r)
tx.Script = make([]byte, lenScript)
if err := binary.Read(r, binary.LittleEndian, tx.Script); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &tx.Gas)
br := util.BinReader{R: r}
tx.Script = br.ReadBytes()
br.ReadLE(&tx.Gas)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (tx *InvocationTX) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(tx.Script))); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, tx.Script); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, tx.Gas)
bw := util.BinWriter{W: w}
bw.WriteBytes(tx.Script)
bw.WriteLE(tx.Gas)
return bw.Err
}

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"encoding/json"
"io"
@ -36,24 +35,20 @@ func NewOutput(assetID util.Uint256, amount util.Fixed8, scriptHash util.Uint160
// DecodeBinary implements the Payload interface.
func (out *Output) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &out.AssetID); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &out.Amount); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &out.ScriptHash)
br := util.BinReader{R: r}
br.ReadLE(&out.AssetID)
br.ReadLE(&out.Amount)
br.ReadLE(&out.ScriptHash)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (out *Output) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, out.AssetID); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, out.Amount); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, out.ScriptHash)
bw := util.BinWriter{W: w}
bw.WriteLE(out.AssetID)
bw.WriteLE(out.Amount)
bw.WriteLE(out.ScriptHash)
return bw.Err
}
// Size returns the size in bytes of the Output

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/smartcontract"
@ -24,55 +23,30 @@ type PublishTX struct {
// DecodeBinary implements the Payload interface.
func (tx *PublishTX) DecodeBinary(r io.Reader) error {
var err error
br := util.BinReader{R: r}
tx.Script = br.ReadBytes()
tx.Script, err = util.ReadVarBytes(r)
if err != nil {
return err
}
lenParams := util.ReadVarUint(r)
lenParams := br.ReadVarUint()
tx.ParamList = make([]smartcontract.ParamType, lenParams)
for i := 0; i < int(lenParams); i++ {
var ptype uint8
if err := binary.Read(r, binary.LittleEndian, &ptype); err != nil {
return err
}
br.ReadLE(&ptype)
tx.ParamList[i] = smartcontract.ParamType(ptype)
}
var rtype uint8
if err := binary.Read(r, binary.LittleEndian, &rtype); err != nil {
return err
}
br.ReadLE(&rtype)
tx.ReturnType = smartcontract.ParamType(rtype)
if err := binary.Read(r, binary.LittleEndian, &tx.NeedStorage); err != nil {
return err
}
br.ReadLE(&tx.NeedStorage)
tx.Name, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.CodeVersion, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.Author, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.Email, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.Description, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.Name = br.ReadString()
tx.CodeVersion = br.ReadString()
tx.Author = br.ReadString()
tx.Email = br.ReadString()
tx.Description = br.ReadString()
return nil
return br.Err
}
// EncodeBinary implements the Payload interface.

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
@ -32,22 +31,15 @@ type RegisterTX struct {
// DecodeBinary implements the Payload interface.
func (tx *RegisterTX) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &tx.AssetType); err != nil {
return err
}
br := util.BinReader{R: r}
br.ReadLE(&tx.AssetType)
var err error
tx.Name, err = util.ReadVarString(r)
if err != nil {
return err
}
tx.Name = br.ReadString()
if err := binary.Read(r, binary.LittleEndian, &tx.Amount); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &tx.Precision); err != nil {
return err
br.ReadLE(&tx.Amount)
br.ReadLE(&tx.Precision)
if br.Err != nil {
return br.Err
}
tx.Owner = &keys.PublicKey{}
@ -55,25 +47,18 @@ func (tx *RegisterTX) DecodeBinary(r io.Reader) error {
return err
}
return binary.Read(r, binary.LittleEndian, &tx.Admin)
br.ReadLE(&tx.Admin)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (tx *RegisterTX) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, tx.AssetType); err != nil {
return err
}
if err := util.WriteVarString(w, tx.Name); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, tx.Amount); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, tx.Precision); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, tx.Owner.Bytes()); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, tx.Admin)
bw := util.BinWriter{W: w}
bw.WriteLE(tx.AssetType)
bw.WriteString(tx.Name)
bw.WriteLE(tx.Amount)
bw.WriteLE(tx.Precision)
bw.WriteLE(tx.Owner.Bytes())
bw.WriteLE(tx.Admin)
return bw.Err
}

View file

@ -13,7 +13,11 @@ type StateTX struct {
// DecodeBinary implements the Payload interface.
func (tx *StateTX) DecodeBinary(r io.Reader) error {
lenDesc := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenDesc := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
for i := 0; i < int(lenDesc); i++ {
tx.Descriptors[i] = &StateDescriptor{}
if err := tx.Descriptors[i].DecodeBinary(r); err != nil {

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -26,30 +25,14 @@ type StateDescriptor struct {
// DecodeBinary implements the Payload interface.
func (s *StateDescriptor) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &s.Type); err != nil {
return err
}
br := util.BinReader{R: r}
br.ReadLE(&s.Type)
keyLen := util.ReadVarUint(r)
s.Key = make([]byte, keyLen)
if err := binary.Read(r, binary.LittleEndian, s.Key); err != nil {
return err
}
s.Key = br.ReadBytes()
s.Value = br.ReadBytes()
s.Field = br.ReadString()
valLen := util.ReadVarUint(r)
s.Value = make([]byte, valLen)
if err := binary.Read(r, binary.LittleEndian, s.Value); err != nil {
return err
}
fieldLen := util.ReadVarUint(r)
field := make([]byte, fieldLen)
if err := binary.Read(r, binary.LittleEndian, field); err != nil {
return err
}
s.Field = string(field)
return nil
return br.Err
}
// EncodeBinary implements the Payload interface.

View file

@ -2,7 +2,6 @@ package transaction
import (
"bytes"
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
@ -79,17 +78,17 @@ func (t *Transaction) AddInput(in *Input) {
// DecodeBinary implements the payload interface.
func (t *Transaction) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &t.Type); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &t.Version); err != nil {
return err
br := util.BinReader{R: r}
br.ReadLE(&t.Type)
br.ReadLE(&t.Version)
if br.Err != nil {
return br.Err
}
if err := t.decodeData(r); err != nil {
return err
}
lenAttrs := util.ReadVarUint(r)
lenAttrs := br.ReadVarUint()
t.Attributes = make([]*Attribute, lenAttrs)
for i := 0; i < int(lenAttrs); i++ {
t.Attributes[i] = &Attribute{}
@ -100,7 +99,7 @@ func (t *Transaction) DecodeBinary(r io.Reader) error {
}
}
lenInputs := util.ReadVarUint(r)
lenInputs := br.ReadVarUint()
t.Inputs = make([]*Input, lenInputs)
for i := 0; i < int(lenInputs); i++ {
t.Inputs[i] = &Input{}
@ -109,7 +108,7 @@ func (t *Transaction) DecodeBinary(r io.Reader) error {
}
}
lenOutputs := util.ReadVarUint(r)
lenOutputs := br.ReadVarUint()
t.Outputs = make([]*Output, lenOutputs)
for i := 0; i < int(lenOutputs); i++ {
t.Outputs[i] = &Output{}
@ -118,7 +117,7 @@ func (t *Transaction) DecodeBinary(r io.Reader) error {
}
}
lenScripts := util.ReadVarUint(r)
lenScripts := br.ReadVarUint()
t.Scripts = make([]*Witness, lenScripts)
for i := 0; i < int(lenScripts); i++ {
t.Scripts[i] = &Witness{}
@ -127,6 +126,9 @@ func (t *Transaction) DecodeBinary(r io.Reader) error {
}
}
if br.Err != nil {
return br.Err
}
// Create the hash of the transaction at decode, so we dont need
// to do it anymore.
return t.createHash()
@ -172,8 +174,10 @@ func (t *Transaction) EncodeBinary(w io.Writer) error {
if err := t.encodeHashableFields(w); err != nil {
return err
}
if err := util.WriteVarUint(w, uint64(len(t.Scripts))); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(t.Scripts)))
if bw.Err != nil {
return bw.Err
}
for _, s := range t.Scripts {
if err := s.EncodeBinary(w); err != nil {
@ -186,11 +190,12 @@ func (t *Transaction) EncodeBinary(w io.Writer) error {
// encodeHashableFields will only encode the fields that are not used for
// signing the transaction, which are all fields except the scripts.
func (t *Transaction) encodeHashableFields(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, t.Type); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, t.Version); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteLE(t.Type)
bw.WriteLE(t.Version)
if bw.Err != nil {
return bw.Err
}
// Underlying TXer.
@ -201,9 +206,9 @@ func (t *Transaction) encodeHashableFields(w io.Writer) error {
}
// Attributes
lenAttrs := uint64(len(t.Attributes))
if err := util.WriteVarUint(w, lenAttrs); err != nil {
return err
bw.WriteVarUint(uint64(len(t.Attributes)))
if bw.Err != nil {
return bw.Err
}
for _, attr := range t.Attributes {
if err := attr.EncodeBinary(w); err != nil {
@ -212,8 +217,9 @@ func (t *Transaction) encodeHashableFields(w io.Writer) error {
}
// Inputs
if err := util.WriteVarUint(w, uint64(len(t.Inputs))); err != nil {
return err
bw.WriteVarUint(uint64(len(t.Inputs)))
if bw.Err != nil {
return bw.Err
}
for _, in := range t.Inputs {
if err := in.EncodeBinary(w); err != nil {
@ -222,8 +228,9 @@ func (t *Transaction) encodeHashableFields(w io.Writer) error {
}
// Outputs
if err := util.WriteVarUint(w, uint64(len(t.Outputs))); err != nil {
return err
bw.WriteVarUint(uint64(len(t.Outputs)))
if bw.Err != nil {
return bw.Err
}
for _, out := range t.Outputs {
if err := out.EncodeBinary(w); err != nil {

View file

@ -1,7 +1,6 @@
package transaction
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"io"
@ -18,28 +17,21 @@ type Witness struct {
// DecodeBinary implements the payload interface.
func (w *Witness) DecodeBinary(r io.Reader) error {
lenb := util.ReadVarUint(r)
w.InvocationScript = make([]byte, lenb)
if err := binary.Read(r, binary.LittleEndian, w.InvocationScript); err != nil {
return err
}
lenb = util.ReadVarUint(r)
w.VerificationScript = make([]byte, lenb)
return binary.Read(r, binary.LittleEndian, w.VerificationScript)
br := util.BinReader{R: r}
w.InvocationScript = br.ReadBytes()
w.VerificationScript = br.ReadBytes()
return br.Err
}
// EncodeBinary implements the payload interface.
func (w *Witness) EncodeBinary(writer io.Writer) error {
if err := util.WriteVarUint(writer, uint64(len(w.InvocationScript))); err != nil {
return err
}
if err := binary.Write(writer, binary.LittleEndian, w.InvocationScript); err != nil {
return err
}
if err := util.WriteVarUint(writer, uint64(len(w.VerificationScript))); err != nil {
return err
}
return binary.Write(writer, binary.LittleEndian, w.VerificationScript)
bw := util.BinWriter{W: writer}
bw.WriteBytes(w.InvocationScript)
bw.WriteBytes(w.VerificationScript)
return bw.Err
}
// MarshalJSON implements the json marshaller interface.

View file

@ -2,7 +2,6 @@ package core
import (
"bytes"
"encoding/binary"
"fmt"
"io"
@ -68,29 +67,25 @@ func (u UnspentCoins) commit(b storage.Batch) error {
// EncodeBinary encodes UnspentCoinState to the given io.Writer.
func (s *UnspentCoinState) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(s.states))); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(s.states)))
for _, state := range s.states {
if err := binary.Write(w, binary.LittleEndian, byte(state)); err != nil {
return err
}
bw.WriteLE(byte(state))
}
return nil
return bw.Err
}
// DecodeBinary decodes UnspentCoinState from the given io.Reader.
func (s *UnspentCoinState) DecodeBinary(r io.Reader) error {
lenStates := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenStates := br.ReadVarUint()
s.states = make([]CoinState, lenStates)
for i := 0; i < int(lenStates); i++ {
var state uint8
if err := binary.Read(r, binary.LittleEndian, &state); err != nil {
return err
}
br.ReadLE(&state)
s.states[i] = CoinState(state)
}
return nil
return br.Err
}
// IsDoubleSpend verifies that the input transactions are not double spent.

View file

@ -12,6 +12,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
"github.com/CityOfZion/neo-go/pkg/network/payload"
"github.com/CityOfZion/neo-go/pkg/util"
)
const (
@ -49,23 +50,26 @@ type CommandType string
// Valid protocol commands used to send between nodes.
const (
CMDVersion CommandType = "version"
CMDVerack CommandType = "verack"
CMDGetAddr CommandType = "getaddr"
CMDAddr CommandType = "addr"
CMDGetHeaders CommandType = "getheaders"
CMDHeaders CommandType = "headers"
CMDGetBlocks CommandType = "getblocks"
CMDInv CommandType = "inv"
CMDGetData CommandType = "getdata"
CMDBlock CommandType = "block"
CMDTX CommandType = "tx"
CMDConsensus CommandType = "consensus"
CMDUnknown CommandType = "unknown"
CMDFilterAdd CommandType = "filteradd"
CMDFilterClear CommandType = "filterclear"
CMDFilterLoad CommandType = "filterload"
CMDGetAddr CommandType = "getaddr"
CMDGetBlocks CommandType = "getblocks"
CMDGetData CommandType = "getdata"
CMDGetHeaders CommandType = "getheaders"
CMDHeaders CommandType = "headers"
CMDInv CommandType = "inv"
CMDMempool CommandType = "mempool"
CMDMerkleBlock CommandType = "merkleblock"
CMDPing CommandType = "ping"
CMDPong CommandType = "pong"
CMDTX CommandType = "tx"
CMDUnknown CommandType = "unknown"
CMDVerack CommandType = "verack"
CMDVersion CommandType = "version"
)
// NewMessage returns a new message with the given payload.
@ -99,38 +103,44 @@ func NewMessage(magic config.NetMode, cmd CommandType, p payload.Payload) *Messa
func (m *Message) CommandType() CommandType {
cmd := cmdByteArrayToString(m.Command)
switch cmd {
case "version":
return CMDVersion
case "verack":
return CMDVerack
case "getaddr":
return CMDGetAddr
case "addr":
return CMDAddr
case "getheaders":
return CMDGetHeaders
case "headers":
return CMDHeaders
case "getblocks":
return CMDGetBlocks
case "inv":
return CMDInv
case "getdata":
return CMDGetData
case "block":
return CMDBlock
case "tx":
return CMDTX
case "consensus":
return CMDConsensus
case "merkleblock":
return CMDMerkleBlock
case "filterload":
return CMDFilterLoad
case "filteradd":
return CMDFilterAdd
case "filterclear":
return CMDFilterClear
case "filterload":
return CMDFilterLoad
case "getaddr":
return CMDGetAddr
case "getblocks":
return CMDGetBlocks
case "getdata":
return CMDGetData
case "getheaders":
return CMDGetHeaders
case "headers":
return CMDHeaders
case "inv":
return CMDInv
case "mempool":
return CMDMempool
case "merkleblock":
return CMDMerkleBlock
case "ping":
return CMDPing
case "pong":
return CMDPong
case "tx":
return CMDTX
case "verack":
return CMDVerack
case "version":
return CMDVersion
default:
return CMDUnknown
}
@ -138,17 +148,13 @@ func (m *Message) CommandType() CommandType {
// Decode a Message from the given reader.
func (m *Message) Decode(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &m.Magic); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &m.Command); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &m.Length); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &m.Checksum); err != nil {
return err
br := util.BinReader{R: r}
br.ReadLE(&m.Magic)
br.ReadLE(&m.Command)
br.ReadLE(&m.Length)
br.ReadLE(&m.Checksum)
if br.Err != nil {
return br.Err
}
// return if their is no payload.
if m.Length == 0 {
@ -224,17 +230,13 @@ func (m *Message) decodePayload(r io.Reader) error {
// Encode a Message to any given io.Writer.
func (m *Message) Encode(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, m.Magic); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, m.Command); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, m.Length); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, m.Checksum); err != nil {
return err
br := util.BinWriter{W: w}
br.WriteLE(m.Magic)
br.WriteLE(m.Command)
br.WriteLE(m.Length)
br.WriteLE(m.Checksum)
if br.Err != nil {
return br.Err
}
if m.Payload != nil {
return m.Payload.EncodeBinary(w)

View file

@ -1,7 +1,6 @@
package payload
import (
"encoding/binary"
"io"
"time"
@ -26,30 +25,22 @@ func NewAddressAndTime(e util.Endpoint, t time.Time) *AddressAndTime {
// DecodeBinary implements the Payload interface.
func (p *AddressAndTime) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &p.Timestamp); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.Services); err != nil {
return err
}
if err := binary.Read(r, binary.BigEndian, &p.Endpoint.IP); err != nil {
return err
}
return binary.Read(r, binary.BigEndian, &p.Endpoint.Port)
br := util.BinReader{R: r}
br.ReadLE(&p.Timestamp)
br.ReadLE(&p.Services)
br.ReadBE(&p.Endpoint.IP)
br.ReadBE(&p.Endpoint.Port)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (p *AddressAndTime) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, p.Timestamp); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.Services); err != nil {
return err
}
if err := binary.Write(w, binary.BigEndian, p.Endpoint.IP); err != nil {
return err
}
return binary.Write(w, binary.BigEndian, p.Endpoint.Port)
bw := util.BinWriter{W: w}
bw.WriteLE(p.Timestamp)
bw.WriteLE(p.Services)
bw.WriteBE(p.Endpoint.IP)
bw.WriteBE(p.Endpoint.Port)
return bw.Err
}
// AddressList is a list with AddrAndTime.
@ -59,7 +50,11 @@ type AddressList struct {
// DecodeBinary implements the Payload interface.
func (p *AddressList) DecodeBinary(r io.Reader) error {
listLen := util.ReadVarUint(r)
br := util.BinReader{R: r}
listLen := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
p.Addrs = make([]*AddressAndTime, listLen)
for i := 0; i < int(listLen); i++ {
@ -73,8 +68,10 @@ func (p *AddressList) DecodeBinary(r io.Reader) error {
// EncodeBinary implements the Payload interface.
func (p *AddressList) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(p.Addrs))); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(p.Addrs)))
if bw.Err != nil {
return bw.Err
}
for _, addr := range p.Addrs {
if err := addr.EncodeBinary(w); err != nil {

View file

@ -1,7 +1,6 @@
package payload
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -25,24 +24,22 @@ func NewGetBlocks(start []util.Uint256, stop util.Uint256) *GetBlocks {
// DecodeBinary implements the payload interface.
func (p *GetBlocks) DecodeBinary(r io.Reader) error {
lenStart := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenStart := br.ReadVarUint()
p.HashStart = make([]util.Uint256, lenStart)
if err := binary.Read(r, binary.LittleEndian, &p.HashStart); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &p.HashStop)
br.ReadLE(&p.HashStart)
br.ReadLE(&p.HashStop)
return br.Err
}
// EncodeBinary implements the payload interface.
func (p *GetBlocks) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(p.HashStart))); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.HashStart); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, p.HashStop)
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(p.HashStart)))
bw.WriteLE(p.HashStart)
bw.WriteLE(p.HashStop)
return bw.Err
}
// Size implements the payload interface.

View file

@ -14,7 +14,11 @@ type Headers struct {
// DecodeBinary implements the Payload interface.
func (p *Headers) DecodeBinary(r io.Reader) error {
lenHeaders := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenHeaders := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
p.Hdrs = make([]*core.Header, lenHeaders)
@ -31,9 +35,12 @@ func (p *Headers) DecodeBinary(r io.Reader) error {
// EncodeBinary implements the Payload interface.
func (p *Headers) EncodeBinary(w io.Writer) error {
if err := util.WriteVarUint(w, uint64(len(p.Hdrs))); err != nil {
return err
bw := util.BinWriter{W: w}
bw.WriteVarUint(uint64(len(p.Hdrs)))
if bw.Err != nil {
return bw.Err
}
for _, header := range p.Hdrs {
if err := header.EncodeBinary(w); err != nil {
return err

View file

@ -1,7 +1,6 @@
package payload
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/util"
@ -58,36 +57,28 @@ func NewInventory(typ InventoryType, hashes []util.Uint256) *Inventory {
// DecodeBinary implements the Payload interface.
func (p *Inventory) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &p.Type); err != nil {
return err
}
br := util.BinReader{R: r}
br.ReadLE(&p.Type)
listLen := util.ReadVarUint(r)
listLen := br.ReadVarUint()
p.Hashes = make([]util.Uint256, listLen)
for i := 0; i < int(listLen); i++ {
if err := binary.Read(r, binary.LittleEndian, &p.Hashes[i]); err != nil {
return err
}
br.ReadLE(&p.Hashes[i])
}
return nil
return br.Err
}
// EncodeBinary implements the Payload interface.
func (p *Inventory) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, p.Type); err != nil {
return err
}
bw := util.BinWriter{W: w}
bw.WriteLE(p.Type)
listLen := len(p.Hashes)
if err := util.WriteVarUint(w, uint64(listLen)); err != nil {
return err
}
for i := 0; i < len(p.Hashes); i++ {
if err := binary.Write(w, binary.LittleEndian, p.Hashes[i]); err != nil {
return err
}
bw.WriteVarUint(uint64(listLen))
for i := 0; i < listLen; i++ {
bw.WriteLE(p.Hashes[i])
}
return nil
return bw.Err
}

View file

@ -1,7 +1,6 @@
package payload
import (
"encoding/binary"
"io"
"github.com/CityOfZion/neo-go/pkg/core"
@ -20,18 +19,16 @@ func (m *MerkleBlock) DecodeBinary(r io.Reader) error {
if err := m.BlockBase.DecodeBinary(r); err != nil {
return err
}
br := util.BinReader{R: r}
m.TxCount = int(util.ReadVarUint(r))
n := util.ReadVarUint(r)
m.TxCount = int(br.ReadVarUint())
n := br.ReadVarUint()
m.Hashes = make([]util.Uint256, n)
for i := 0; i < len(m.Hashes); i++ {
if err := binary.Read(r, binary.LittleEndian, &m.Hashes[i]); err != nil {
return err
}
br.ReadLE(&m.Hashes[i])
}
var err error
m.Flags, err = util.ReadVarBytes(r)
return err
m.Flags = br.ReadBytes()
return br.Err
}
func (m *MerkleBlock) EncodeBinary(w io.Writer) error {

View file

@ -1,13 +1,23 @@
package payload
import (
"encoding/binary"
"io"
"time"
"github.com/CityOfZion/neo-go/pkg/util"
)
const minVersionSize = 27
// List of Services offered by the node
const (
nodePeerService uint64 = 1
// BloomFilerService uint64 = 2 // Not implemented
// PrunedNode uint64 = 3 // Not implemented
// LightNode uint64 = 4 // Not implemented
)
// Version payload.
type Version struct {
// currently the version of the protocol is 0
@ -32,7 +42,7 @@ type Version struct {
func NewVersion(id uint32, p uint16, ua string, h uint32, r bool) *Version {
return &Version{
Version: 0,
Services: 1,
Services: nodePeerService,
Timestamp: uint32(time.Now().UTC().Unix()),
Port: p,
Nonce: id,
@ -44,63 +54,31 @@ func NewVersion(id uint32, p uint16, ua string, h uint32, r bool) *Version {
// DecodeBinary implements the Payload interface.
func (p *Version) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &p.Version); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.Services); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.Timestamp); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.Port); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.Nonce); err != nil {
return err
}
var lenUA uint8
if err := binary.Read(r, binary.LittleEndian, &lenUA); err != nil {
return err
}
p.UserAgent = make([]byte, lenUA)
if err := binary.Read(r, binary.LittleEndian, &p.UserAgent); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &p.StartHeight); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &p.Relay)
br := util.BinReader{R: r}
br.ReadLE(&p.Version)
br.ReadLE(&p.Services)
br.ReadLE(&p.Timestamp)
br.ReadLE(&p.Port)
br.ReadLE(&p.Nonce)
p.UserAgent = br.ReadBytes()
br.ReadLE(&p.StartHeight)
br.ReadLE(&p.Relay)
return br.Err
}
// EncodeBinary implements the Payload interface.
func (p *Version) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, p.Version); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.Services); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.Timestamp); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.Port); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.Nonce); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, uint8(len(p.UserAgent))); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.UserAgent); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, p.StartHeight); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, p.Relay)
br := util.BinWriter{W: w}
br.WriteLE(p.Version)
br.WriteLE(p.Services)
br.WriteLE(p.Timestamp)
br.WriteLE(p.Port)
br.WriteLE(p.Nonce)
br.WriteBytes(p.UserAgent)
br.WriteLE(p.StartHeight)
br.WriteLE(&p.Relay)
return br.Err
}
// Size implements the payloader interface.

View file

@ -23,19 +23,21 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
}
buf := bytes.NewBuffer(out)
b, _ := buf.ReadByte()
br := util.BinReader{R: buf}
var b uint8
br.ReadLE(&b)
assert.Equal(t, vm.PUSH3, vm.Instruction(b))
for i := 0; i < len(validators); i++ {
b, err := util.ReadVarBytes(buf)
bb := br.ReadBytes()
if err != nil {
t.Fatal(err)
}
assert.Equal(t, validators[i].Bytes(), b)
assert.Equal(t, validators[i].Bytes(), bb)
}
b, _ = buf.ReadByte()
br.ReadLE(&b)
assert.Equal(t, vm.PUSH3, vm.Instruction(b))
b, _ = buf.ReadByte()
br.ReadLE(&b)
assert.Equal(t, vm.CHECKMULTISIG, vm.Instruction(b))
}

View file

@ -12,27 +12,31 @@ type BinReader struct {
Err error
}
// Read reads from the underlying io.Reader
// into the interface v in LE
func (r *BinReader) Read(v interface{}) {
// ReadLE reads from the underlying io.Reader
// into the interface v in little-endian format
func (r *BinReader) ReadLE(v interface{}) {
if r.Err != nil {
return
}
r.Err = binary.Read(r.R, binary.LittleEndian, v)
}
// ReadBigEnd reads from the underlying io.Reader
// into the interface v in BE
func (r *BinReader) ReadBigEnd(v interface{}) {
// ReadBE reads from the underlying io.Reader
// into the interface v in big-endian format
func (r *BinReader) ReadBE(v interface{}) {
if r.Err != nil {
return
}
r.Err = binary.Read(r.R, binary.BigEndian, v)
}
//VarUint reads a variable integer from the
// ReadVarUint reads a variable-length-encoded integer from the
// underlying reader
func (r *BinReader) VarUint() uint64 {
func (r *BinReader) ReadVarUint() uint64 {
if r.Err != nil {
return 0
}
var b uint8
r.Err = binary.Read(r.R, binary.LittleEndian, &b)
@ -55,17 +59,17 @@ func (r *BinReader) VarUint() uint64 {
return uint64(b)
}
// VarBytes reads the next set of bytes from the underlying reader.
// VarUInt is used to determine how large that slice is
func (r *BinReader) VarBytes() []byte {
n := r.VarUint()
// ReadBytes reads the next set of bytes from the underlying reader.
// ReadVarUInt() is used to determine how large that slice is
func (r *BinReader) ReadBytes() []byte {
n := r.ReadVarUint()
b := make([]byte, n)
r.Read(b)
r.ReadLE(b)
return b
}
// VarString calls VarBytes and casts the results as a string
func (r *BinReader) VarString() string {
b := r.VarBytes()
// ReadString calls ReadBytes and casts the results as a string
func (r *BinReader) ReadString() string {
b := r.ReadBytes()
return string(b)
}

View file

@ -14,25 +14,28 @@ type BinWriter struct {
Err error
}
// Write writes into the underlying io.Writer from an object v in LE format
func (w *BinWriter) Write(v interface{}) {
// WriteLE writes into the underlying io.Writer from an object v in little-endian format
func (w *BinWriter) WriteLE(v interface{}) {
if w.Err != nil {
return
}
w.Err = binary.Write(w.W, binary.LittleEndian, v)
}
// WriteBigEnd writes into the underlying io.Writer from an object v in BE format
// Only used for IP and PORT. Additional method makes the default LittleEndian case clean
func (w *BinWriter) WriteBigEnd(v interface{}) {
// WriteBE writes into the underlying io.Writer from an object v in big-endian format
func (w *BinWriter) WriteBE(v interface{}) {
if w.Err != nil {
return
}
w.Err = binary.Write(w.W, binary.BigEndian, v)
}
// VarUint writes a uint64 into the underlying writer
func (w *BinWriter) VarUint(val uint64) {
// WriteVarUint writes a uint64 into the underlying writer using variable-length encoding
func (w *BinWriter) WriteVarUint(val uint64) {
if w.Err != nil {
return
}
if val < 0 {
w.Err = errors.New("value out of range")
return
@ -63,13 +66,13 @@ func (w *BinWriter) VarUint(val uint64) {
}
// VarBytes writes a variable length byte array into the underlying io.Writer
func (w *BinWriter) VarBytes(b []byte) {
w.VarUint(uint64(len(b)))
w.Write(b)
// WriteBytes writes a variable length byte array into the underlying io.Writer
func (w *BinWriter) WriteBytes(b []byte) {
w.WriteVarUint(uint64(len(b)))
w.WriteLE(b)
}
//VarString casts the string as a byte slice and calls VarBytes
func (w *BinWriter) VarString(s string) {
w.VarBytes([]byte(s))
// WriteString writes a variable length string into the underlying io.Writer
func (w *BinWriter) WriteString(s string) {
w.WriteBytes([]byte(s))
}

View file

@ -12,9 +12,9 @@ func TestWriteVarUint1(t *testing.T) {
val = uint64(1)
buf = new(bytes.Buffer)
)
if err := WriteVarUint(buf, val); err != nil {
t.Fatal(err)
}
bw := BinWriter{W: buf}
bw.WriteVarUint(val)
assert.Nil(t, bw.Err)
assert.Equal(t, 1, buf.Len())
}
@ -23,13 +23,14 @@ func TestWriteVarUint1000(t *testing.T) {
val = uint64(1000)
buf = new(bytes.Buffer)
)
if err := WriteVarUint(buf, val); err != nil {
t.Fatal(err)
}
bw := BinWriter{W: buf}
bw.WriteVarUint(val)
assert.Nil(t, bw.Err)
assert.Equal(t, 3, buf.Len())
assert.Equal(t, byte(0xfd), buf.Bytes()[0])
res := ReadVarUint(buf)
br := BinReader{R: buf}
res := br.ReadVarUint()
assert.Nil(t, br.Err)
assert.Equal(t, val, res)
}
@ -38,13 +39,14 @@ func TestWriteVarUint100000(t *testing.T) {
val = uint64(100000)
buf = new(bytes.Buffer)
)
if err := WriteVarUint(buf, val); err != nil {
t.Fatal(err)
}
bw := BinWriter{W: buf}
bw.WriteVarUint(val)
assert.Nil(t, bw.Err)
assert.Equal(t, 5, buf.Len())
assert.Equal(t, byte(0xfe), buf.Bytes()[0])
res := ReadVarUint(buf)
br := BinReader{R: buf}
res := br.ReadVarUint()
assert.Nil(t, br.Err)
assert.Equal(t, val, res)
}
@ -53,12 +55,13 @@ func TestWriteVarUint100000000000(t *testing.T) {
val = uint64(1000000000000)
buf = new(bytes.Buffer)
)
if err := WriteVarUint(buf, val); err != nil {
t.Fatal(err)
}
bw := BinWriter{W: buf}
bw.WriteVarUint(val)
assert.Nil(t, bw.Err)
assert.Equal(t, 9, buf.Len())
assert.Equal(t, byte(0xff), buf.Bytes()[0])
res := ReadVarUint(buf)
br := BinReader{R: buf}
res := br.ReadVarUint()
assert.Nil(t, br.Err)
assert.Equal(t, val, res)
}

View file

@ -1,103 +0,0 @@
package util
import (
"bytes"
"encoding/binary"
"io"
)
// Variable length integer, can be encoded to save space according to the value typed.
// len 1 uint8
// len 3 0xfd + uint16
// len 5 0xfe = uint32
// len 9 0xff = uint64
// For more information about this:
// https://github.com/neo-project/neo/wiki/Network-Protocol
// ReadVarUint reads a variable unsigned integer and returns it as a uint64.
func ReadVarUint(r io.Reader) uint64 {
var b uint8
binary.Read(r, binary.LittleEndian, &b)
switch b {
case 0xfd:
var v uint16
binary.Read(r, binary.LittleEndian, &v)
return uint64(v)
case 0xfe:
var v uint32
binary.Read(r, binary.LittleEndian, &v)
return uint64(v)
case 0xff:
var v uint64
binary.Read(r, binary.LittleEndian, &v)
return v
default:
return uint64(b)
}
}
// WriteVarUint writes a variable unsigned integer.
func WriteVarUint(w io.Writer, val uint64) error {
if val < 0xfd {
return binary.Write(w, binary.LittleEndian, uint8(val))
}
if val < 0xFFFF {
if err := binary.Write(w, binary.LittleEndian, byte(0xfd)); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, uint16(val))
}
if val < 0xFFFFFFFF {
if err := binary.Write(w, binary.LittleEndian, byte(0xfe)); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, uint32(val))
}
if err := binary.Write(w, binary.LittleEndian, byte(0xff)); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, val)
}
// ReadVarBytes reads a variable length byte array.
func ReadVarBytes(r io.Reader) ([]byte, error) {
n := ReadVarUint(r)
b := make([]byte, n)
if err := binary.Read(r, binary.LittleEndian, b); err != nil {
return nil, err
}
return b, nil
}
// ReadVarString reads a variable length string.
func ReadVarString(r io.Reader) (string, error) {
b, err := ReadVarBytes(r)
return string(b), err
}
// WriteVarString writes a variable length string.
func WriteVarString(w io.Writer, s string) error {
return WriteVarBytes(w, []byte(s))
}
// WriteVarBytes writes a variable length byte array.
func WriteVarBytes(w io.Writer, b []byte) error {
if err := WriteVarUint(w, uint64(len(b))); err != nil {
return err
}
return binary.Write(w, binary.LittleEndian, b)
}
// Read2000Uint256Hashes attempt to read 2000 Uint256 hashes from
// the given byte array.
func Read2000Uint256Hashes(b []byte) ([]Uint256, error) {
r := bytes.NewReader(b)
lenHashes := ReadVarUint(r)
hashes := make([]Uint256, lenHashes)
if err := binary.Read(r, binary.LittleEndian, hashes); err != nil {
return nil, err
}
return hashes, nil
}