pkg/core: use util.binaryReader/Writer

Simplify error handling.
This commit is contained in:
Roman Khimov 2019-08-28 19:27:06 +03:00
parent 459542a978
commit 361724a33e
19 changed files with 291 additions and 467 deletions

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
bw.WriteLE(k)
bw.WriteLE(v)
}
if err := binary.Write(w, binary.LittleEndian, v); err != nil {
return err
}
}
return nil
return bw.Err
}

View file

@ -84,10 +84,12 @@ func HeaderHashes(s Store) ([]util.Uint256, error) {
// the given byte array.
func read2000Uint256Hashes(b []byte) ([]util.Uint256, error) {
r := bytes.NewReader(b)
lenHashes := util.ReadVarUint(r)
br := util.BinReader{R: r}
lenHashes := br.ReadVarUint()
hashes := make([]util.Uint256, lenHashes)
if err := binary.Read(r, binary.LittleEndian, hashes); err != nil {
return nil, err
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:])
}
if attr.Usage == Script {
attr.Data = make([]byte, 20)
return binary.Read(r, binary.LittleEndian, attr.Data)
}
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)
br.ReadLE(attr.Data[1:])
return br.Err
}
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)
}
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
}
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)
}
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)
}
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.